PHP: comprueba si dos matrices son iguales

280

Me gustaría comprobar si dos matrices son iguales. Quiero decir: mismo tamaño, mismo índice, mismos valores. ¿Cómo puedo hacer eso?

Utilizando !==según lo sugerido por un usuario, espero que lo siguiente imprima enter si al menos un elemento en la matriz (s) es diferente, pero de hecho no lo hace.

if (($_POST['atlOriginal'] !== $oldAtlPosition) 
    or ($_POST['atl'] !== $aext) 
    or ($_POST['sidesOriginal'] !== $oldSidePosition) 
    or ($_POST['sidesOriginal'] !== $sideext)) {

    echo "enter";
}
markzzz
fuente
17
Estás usando =demasiado, debería ser !==o!=
jeroen
29
Solo para el registro (ya que mi edición volvió a cambiar a "un usuario") es "un usuario": english.stackexchange.com/questions/105116/…
teynon
77
['a'] == [0]es true. Bueno, esto es solo PHP.
Dávid Horváth
2
@ DávidHorváth es realmente extraño, una buena práctica para usar siempre ===
AFA Med
1
@ DávidHorváth, la comparación suelta es flexible no solo en PHP. Si miras a JS, te sorprenderás. Simplemente no lo use hasta que comprenda mejor las cosas.
ryabenko-pro

Respuestas:

510
$arraysAreEqual = ($a == $b); // TRUE if $a and $b have the same key/value pairs.
$arraysAreEqual = ($a === $b); // TRUE if $a and $b have the same key/value pairs in the same order and of the same types.

Ver Operadores de matrices .

EDITAR

El operador de desigualdad es !=mientras que el operador de no identidad !==debe coincidir con el operador de igualdad ==y el operador de identidad ===.

Stefan Gehrig
fuente
79
Una nota al margen: este enfoque también funciona para matrices multidimensionales (antes no era tan obvio para mí).
trejder
55
PD: la solución es usar array_values($a)==array_values($b)... Otro problema habitual es sobre valores únicos, así que recuerda que existen array_unique().
Peter Krauss
13
Esta respuesta es incorrecta. ==funciona independientemente del orden solo para diccionarios típicos como [1 => 'a', 2 => 'b']. Por ej [1 => 'a', 2 => 'b'] == [2 => 'b', 1 => 'a']. Para matrices indexadas como ['a', 'b'] ==no funciona como se indica. Por ej ['a', 'b'] != ['b', 'a'].
nawfal
37
@nawfal: Tu suposición es incorrecta. ['a', 'b']es una matriz [0 => 'a', 1 => 'b'], mientras que ['b', 'a']es una matriz [0 => 'b', 1 => 'a']. Es por eso que no tienen los mismos pares clave / valor como se indica en mi respuesta y es por eso ==que no funciona entre ellos.
Stefan Gehrig el
29
@StefanGehrig oh, tienes razón.
Dejaré
88

De acuerdo a esta página .

NOTA: La respuesta aceptada funciona para matrices asociativas, pero no funcionará como se esperaba con las matrices indexadas (explicadas a continuación). Si desea comparar cualquiera de ellos, use esta solución. Además, esta función puede no funcionar con matrices multidimensionales (debido a la naturaleza de la función array_diff).

Probar dos matrices indexadas, qué elementos están en diferente orden, usando $a == $bo $a === $bfallando, por ejemplo:

<?php
    (array("x","y") == array("y","x")) === false;
?>

Eso es porque lo anterior significa:

array(0 => "x", 1 => "y")vs array(0 => "y", 1 => "x").

Para resolver ese problema, use:

<?php
function array_equal($a, $b) {
    return (
         is_array($a) 
         && is_array($b) 
         && count($a) == count($b) 
         && array_diff($a, $b) === array_diff($b, $a)
    );
}
?>

Se agregó la comparación de tamaños de matriz (sugerida por super_ton) ya que puede mejorar la velocidad.

lepe
fuente
2
Atención: no funciona como se esperaba con las matrices multidimensionales
maersu
8
El comentario anterior es falso. Si $ b tiene todos los elementos que $ a tiene más algunos adicionales, las dos matrices no son iguales, pero el código anterior lo dirá.
Ghola
1
podría valer la pena agregar count ($ a) == count ($ b) también
stefan
1
@super_ton: sí, antes de llamar array_diffpodría acelerar la comparación. Lo agregaré Gracias
lepe
3
Desafortunadamente, no funciona en algunos casos, por ejemplo, lo probé con el siguiente caso $a = [1, 2, 2]; $b = [2, 1, 1];y regresó true, pero las dos matrices obviamente no son lo mismo.
AwesomeGuy
33

Intenta serializar. Esto verificará también las submatrices anidadas.

$foo =serialize($array_foo);
$bar =serialize($array_bar);
if ($foo == $bar) echo "Foo and bar are equal";
Iggi
fuente
77
Problemática si las claves y los valores se cambian al igual que al usar la comparación. Sin embargo, suponiendo que se espera que sean 100% iguales, ¡esta es la forma más limpia y fácil de verificar la igualdad profunda!
Kevin Peno
1
¡Supongo que esta es la mejor solución! ¡Puede comparar matrices multidimensionales y asociativas si se ordenaron previamente!
Rafael Moni
13

Solución corta que funciona incluso con matrices cuyas claves se dan en diferente orden:

public static function arrays_are_equal($array1, $array2)
{
    array_multisort($array1);
    array_multisort($array2);
    return ( serialize($array1) === serialize($array2) );
}
Samuel Vicent
fuente
3
Probablemente la mejor respuesta hasta ahora, la mayoría de las respuestas no coinciden si las teclas se desplazan o si se trata de una matriz multidimensional.
AwesomeGuy
11

Compárelos como otros valores:

if($array_a == $array_b) {
  //they are the same
}

Puede leer sobre todos los operadores de matriz aquí: http://php.net/manual/en/language.operators.array.php Tenga en cuenta, por ejemplo, que ===también comprueba que los tipos y el orden de los elementos en las matrices son los mismos.

Emil Vikström
fuente
55
O ===dependiendo del comportamiento deseado.
Matthew Flaschen
9

!===no funcionará porque es un error de sintaxis. La forma correcta es !==(no tres símbolos "iguales a")

Sodhi saab
fuente
5
if (array_diff($a,$b) == array_diff($b,$a)) {
  // Equals
}

if (array_diff($a,$b) != array_diff($b,$a)) {
  // Not Equals
}

Desde mi punto de vista, es mejor usar array_diff que array_intersect porque con las comprobaciones de esta naturaleza, las diferencias devueltas suelen ser menores que las similitudes, de esta manera la conversión de bool consume menos memoria.

Editar Tenga en cuenta que esta solución es para matrices simples y complementa la == y === una publicada anteriormente que solo es válida para los diccionarios.

Marcos Fernández Ramos
fuente
4

array_diff - Calcula la diferencia de matrices

http://php.net/manual/en/function.array-diff.php

array array_diff ( array $array1 , array $array2 [, array $... ] )

Se compara array1con una o más matrices y devuelve los valores array1que no están presentes en ninguna de las otras matrices.

Scherbius.com
fuente
44
El OP quiere "verificar si dos matrices son iguales". array_diffNo puedo decirte eso. Tratar array_diff([1, 2], [1, 2, 'hello']).
marcv
3

Otro método para verificar la igualdad independientemente del orden de valor funciona mediante el uso de http://php.net/manual/en/function.array-intersect.php , de esta manera:

$array1 = array(2,5,3);
$array2 = array(5,2,3);
if($array1 === array_intersect($array1, $array2) && $array2 === array_intersect($array2, $array1)) {
    echo 'Equal';
} else {
    echo 'Not equal';
}

Aquí hay una versión que también funciona con matrices multidimensionales usando http://php.net/manual/en/function.array-uintersect.php :

$array1 = array(
    array(5, 2),
    array(3, 6),
    array(2, 9, 4)
);
$array2 = array(
    array(3, 6),
    array(2, 9, 4),
    array(5, 2)
);

if($array1 === array_uintersect($array1, $array2, 'compare') && $array2 === array_uintersect($array2, $array1, 'compare')) {
    echo 'Equal';
} else {
    echo 'Not equal';
}

function compare($v1, $v2) {
    if ($v1===$v2) {
        return 0;
    }
    if ($v1 > $v2) return 1;
    return -1;
}
ceja
fuente
3
function compareIsEqualArray(array $array1,array $array):bool
{

   return array_diff($array1,$array2)==[];

}
dılo sürücü
fuente
2
Es útil explicar qué está haciendo un ejemplo de código. ¿Esto también funciona para matrices multidimensionales?
k0pernikus
1
array_diff conseguir elemento diferente de la matriz si el retorno array_diff vacío matriz de dos array es igual
dilo Sürücü
2

Una forma: (implementando 'considerado igual' para http://tools.ietf.org/html/rfc6902#section-4.6 )

De esta forma, se permiten matrices asociativas cuyos miembros están ordenados de manera diferente, por ejemplo, se considerarían iguales en todos los idiomas excepto php :)

// recursive ksort
function rksort($a) {
  if (!is_array($a)) {
    return $a;
  }
  foreach (array_keys($a) as $key) {
    $a[$key] = ksort($a[$key]);
  }
  // SORT_STRING seems required, as otherwise
  // numeric indices (e.g. "0") aren't sorted.
  ksort($a, SORT_STRING);
  return $a;
}


// Per http://tools.ietf.org/html/rfc6902#section-4.6
function considered_equal($a1, $a2) {
  return json_encode(rksort($a1)) === json_encode(rksort($a2));
}
Mike McCabe
fuente
1
Creo que debería ser:$a[$key] = rksort($a[$key]);
pinkeen
2

Problema de sintaxis en sus matrices

$array1 = array(
    'a' => 'value1',
    'b' => 'value2',
    'c' => 'value3',
 );

$array2 = array(
    'a' => 'value1',
    'b' => 'value2',
    'c' => 'value3',
 );

$diff = array_diff($array1, $array2);

var_dump($diff); 
YEFFOU WAGOUM THIERRY HENRI
fuente
2

Aquí está el ejemplo de cómo comparar las matrices y obtener lo que es diferente entre ellas.

$array1 = ['1' => 'XXX', 'second' => [
            'a' => ['test' => '2'],
            'b' => 'test'
        ], 'b' => ['no test']];

        $array2 = [
            '1' => 'XX',
            'second' => [
                'a' => ['test' => '5', 'z' => 5],
                'b' => 'test'
            ],
            'test'
        ];


        function compareArrayValues($arrayOne, $arrayTwo, &$diff = [], $reversed = false)
        {
            foreach ($arrayOne as $key => $val) {
                if (!isset($arrayTwo[$key])) {
                    $diff[$key] = 'MISSING IN ' . ($reversed ? 'FIRST' : 'SECOND');
                } else if (is_array($val) && (json_encode($arrayOne[$key]) !== json_encode($arrayTwo[$key]))) {
                    compareArrayValues($arrayOne[$key], $arrayTwo[$key], $diff[$key], $reversed);
                } else if ($arrayOne[$key] !== $arrayTwo[$key]) {
                    $diff[$key] = 'DIFFERENT';
                }
            }
        }

        $diff = [];
        $diffSecond = [];

        compareArrayValues($array1, $array2, $diff);
        compareArrayValues($array2, $array1, $diffSecond, true);

        print_r($diff);
        print_r($diffSecond);

        print_r(array_merge($diff, $diffSecond));

Resultado:

Array
(
    [0] => DIFFERENT
    [second] => Array
        (
            [a] => Array
                (
                    [test] => DIFFERENT
                    [z] => MISSING IN FIRST
                )

        )

    [b] => MISSING IN SECOND
    [1] => DIFFERENT
    [2] => MISSING IN FIRST
)
Marko Šutija
fuente
1

Utilice la función php array_diff (array1, array2);

Devolverá la diferencia entre las matrices. Si está vacío, entonces son iguales.

ejemplo:

$array1 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value3'
 );

$array2 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value4'
 );

$diff = array_diff(array1, array2);

var_dump($diff); 

//it will print array = (0 => ['c'] => 'value4' ) 

Ejemplo 2

$array1 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value3',
 );

$array2 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value3',
 );

$diff = array_diff(array1, array2);

var_dump($diff); 

//it will print empty; 
Wolfgang Leon
fuente
1
Técnicamente, no devuelve la diferencia entre matrices. La documentación establece que "compara la matriz1 con una o más matrices y devuelve los valores de la matriz1 que no están presentes en ninguna de las otras matrices". Entonces, si todos los valores de array1 están presentes en array2, incluso si array2 tiene más valores, array_diff devolverá una matriz vacía
2pha
No "imprime nulo", imprime una matriz vacía (después de corregir aproximadamente una docena de errores de sintaxis). Tal vez podría usar (count(array_diff($a1, $a2)) + count(array_diff($a2, $a1))) === 0para probar si las matrices son "iguales"
user9645
Arregle la sintaxis (no nulo está vacío, y estaba mezclando comas -.-). Lo que estás proponiendo creo que es demasiado. Comprobar si es una matriz vacía debería ser suficiente.
Wolfgang Leon
1

Si desea verificar matrices no asociativas, esta es la solución:

$a = ['blog', 'company'];
$b = ['company', 'blog'];

(count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';
// Equals
Santo Boldižar
fuente