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";
}

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 ===.


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.


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";

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) );
}

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


9

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


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.


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.


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;
}

3
function compareIsEqualArray(array $array1,array $array):bool
{

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

}

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));
}

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); 

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
)

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; 

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.