PHP - Verifique se duas matrizes são iguais

280

Eu gostaria de verificar se duas matrizes são iguais. Quero dizer: mesmo tamanho, mesmo índice, mesmos valores. Como eu posso fazer isso?

Usando !==como sugerido por um usuário, espero que o seguinte imprima enter se pelo menos um elemento na (s) matriz (s) for diferente, mas na verdade não.

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

    echo "enter";
}
markzzz
fonte
17
Você está usando =muito, deveria ser !==ou!=
jeroen 15/04
29
Apenas para o registro (desde a minha edição foi alterado novamente para um "usuário") é "um usuário": english.stackexchange.com/questions/105116/...
teynon
7
['a'] == [0]é true. Bem, isso é apenas PHP.
Dávid Horváth
2
@ DávidHorváth é realmente estranho, é uma boa prática usá-lo sempre ===
AFA Med
1
@ DávidHorváth, a comparação frouxa é frouxa não apenas no PHP. Se você olhar para JS, ficará surpreso. Só não use até entender melhor as coisas.
ryabenko-pro 29/03/19

Respostas:

508
$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.

Consulte Operadores de matriz .

EDITAR

O operador de desigualdade é !=enquanto o operador de não identidade !==deve corresponder ao operador de igualdade ==e ao operador de identidade ===.

Stefan Gehrig
fonte
79
Uma observação: Essa abordagem também funciona com matrizes multidimensionais (não era tão óbvio para mim antes).
Trejder
5
PS: solução é usar array_values($a)==array_values($b)... Outro problema comum é sobre valores únicos, lembre-se de que existem array_unique().
Peter Krauss
13
Esta resposta está errada. ==funciona independentemente da ordem apenas para dicionários típicos como [1 => 'a', 2 => 'b']. Por exemplo [1 => 'a', 2 => 'b'] == [2 => 'b', 1 => 'a']. Para matrizes indexadas, como ['a', 'b'] ==não funciona como indicado. Por exemplo ['a', 'b'] != ['b', 'a'].
Nawfal
37
@nawfal: Sua suposição está errada. ['a', 'b']é uma matriz [0 => 'a', 1 => 'b'], enquanto ['b', 'a']é uma matriz [0 => 'b', 1 => 'a']. É por isso que eles não têm os mesmos pares de chave / valor conforme indicado na minha resposta e é por isso ==que não funciona entre eles.
Stefan Gehrig
29
@StefanGehrig oh você está certo. Vou deixar o meu comentário como tal para fazer minha loucura :) evidente
Nawfal
88

De acordo com esta página .

NOTA: A resposta aceita funciona para matrizes associativas, mas não funcionará conforme o esperado com matrizes indexadas (explicadas abaixo). Se você quiser comparar um deles, use esta solução. Além disso, essa função pode não funcionar com matrizes multidimensionais (devido à natureza da função array_diff).

Testando duas matrizes indexadas, cujos elementos estão em ordem diferente, usando $a == $bou $a === $bfalham, por exemplo:

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

Isso ocorre porque o acima significa:

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

Para resolver esse 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)
    );
}
?>

A comparação de tamanhos de array foi adicionada (sugerida por super_ton), pois pode melhorar a velocidade.

lepe
fonte
2
Atenção: não funciona como esperado com arrays multidimensionais
maersu
8
O comentário acima é falso. Se $ b tiver todos os elementos que $ a tiver mais alguns extras, as duas matrizes não serão iguais, mas o código acima indicará que são.
Ghola
1
pode valer a pena acrescentar count ($ a) == count ($ b) demais
Stefan
1
@ super_ton: sim, antes de ligar, array_diffpoderia acelerar a comparação. Vou adicioná-lo. Obrigado
lepe 8/16
3
Infelizmente, ele não funciona em alguns casos, por exemplo, eu testei com o seguinte caso $a = [1, 2, 2]; $b = [2, 1, 1];e ele retornou true, mas as duas matrizes obviamente não são as mesmas.
precisa saber é o seguinte
33

Tente serializar. Isso também verificará as sub-matrizes aninhadas.

$foo =serialize($array_foo);
$bar =serialize($array_bar);
if ($foo == $bar) echo "Foo and bar are equal";
Iggi
fonte
7
Problema se as chaves e os valores forem alterados da mesma forma que a comparação. No entanto, supondo que eles sejam 100% iguais, essa é a maneira mais limpa e fácil de verificar a igualdade profunda!
Kevin Peno
1
Eu acho que essa é a melhor solução! Ele pode comparar matrizes multidimensionais e associativas se elas foram classificadas anteriormente!
Rafael Moni
13

Solução curta que funciona mesmo com matrizes cujas chaves são fornecidas em ordem diferente:

public static function arrays_are_equal($array1, $array2)
{
    array_multisort($array1);
    array_multisort($array2);
    return ( serialize($array1) === serialize($array2) );
}
Samuel Vicent
fonte
3
Provavelmente a melhor resposta até agora, a maioria das respostas não corresponde se as teclas forem trocadas ou se for uma matriz multidimensional.
precisa saber é o seguinte
11

Compare-os como outros valores:

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

Você pode ler sobre todos os operadores de matriz aqui: http://php.net/manual/en/language.operators.array.php Observe, por exemplo, que ===também verifica se os tipos e a ordem dos elementos nas matrizes são os mesmos.

Emil Vikström
fonte
5
Ou ===dependendo do comportamento desejado.
Matthew Flaschen
9

!===não funcionará porque é um erro de sintaxe. A maneira correta é !==(não três símbolos "iguais a")

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

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

Do meu ponto de vista, é melhor usar array_diff do que array_intersect porque, com verificações dessa natureza, as diferenças retornadas geralmente são menores que as semelhanças, desta forma a conversão de bools consome menos memória.

Editar Observe que esta solução é para matrizes simples e complementa a == e === uma postada acima que é válida apenas para dicionários.

Marcos Fernandez Ramos
fonte
4

array_diff - Calcula a diferença de matrizes

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

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

Compara array1com uma ou mais outras matrizes e retorna os valores array1que não estão presentes em nenhuma das outras matrizes.

Scherbius.com
fonte
4
O OP quer "verificar se duas matrizes são iguais". array_diffnão posso te dizer isso. Tente array_diff([1, 2], [1, 2, 'hello']).
Marcv
3

Outro método para verificar a igualdade, independentemente da ordem do valor, funciona usando http://php.net/manual/en/function.array-intersect.php , da seguinte forma:

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

Aqui está uma versão que também funciona com matrizes multidimensionais 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;
}
sobrancelha branca
fonte
3
function compareIsEqualArray(array $array1,array $array):bool
{

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

}
dılo sürücü
fonte
2
É útil explicar o que um exemplo de código está fazendo. Isso também funciona para matrizes multidimensionais?
K0pernikus
1
array_diff obter elemento diferente da matriz, se array_diff retorno vazio array dois é igual
Dilo Sürücü
2

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

Dessa forma, as matrizes associativas cujos membros são ordenados de maneira diferente - por exemplo, seriam consideradas iguais em todos os idiomas, exceto no 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
fonte
1
Eu acredito que você deve ser:$a[$key] = rksort($a[$key]);
pinkeen
2

Problema de sintaxe em suas matrizes

$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
fonte
2

Aqui está o exemplo de como comparar com matrizes e obter o que há de diferente entre elas.

$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
fonte
1

Use a função php array_diff (array1, array2);

Retornará a diferença entre matrizes. Se estiver vazio, então eles são iguais.

exemplo:

$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' ) 

Exemplo 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
fonte
1
Tecnicamente, ele não retorna a diferença entre matrizes. A documentação afirma "Compara a matriz1 com uma ou mais outras matrizes e retorna os valores na matriz1 que não estão presentes em nenhuma das outras matrizes". Portanto, se todos os valores do array1 estiverem presentes no array2, mesmo que o array2 tenha mais valores, o array_diff retornará um array vazio
2pha
Não "imprime nulo", imprime uma matriz vazia (após corrigir cerca de uma dúzia de erros de sintaxe). Talvez você poderia usar (count(array_diff($a1, $a2)) + count(array_diff($a2, $a1))) === 0para testar se as matrizes são "iguais"
user9645
Corrigi a sintaxe (not null está vazio e eu estava misturando vírgulas -.-). O que você está propondo é demais. Verificar se é uma matriz vazia deve ser suficiente.
Wolfgang Leon
1

Se você deseja verificar matrizes não associativas, aqui está a solução:

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

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