PHP - Vérifiez si deux tableaux sont égaux

280

Je voudrais vérifier si deux tableaux sont égaux. Je veux dire: même taille, même indice, mêmes valeurs. Comment puis je faire ça?

En utilisant !==comme suggéré par un utilisateur, je m'attends à ce que ce qui suit imprime enter si au moins un élément du ou des tableaux est différent, mais en fait ce n'est pas le cas.

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

    echo "enter";
}
markzzz
la source
17
Vous en utilisez =trop, cela devrait être !==ou!=
jeroen
29
Juste pour mémoire (depuis que mon montage est
redevenu
7
['a'] == [0]est true. Eh bien, c'est juste PHP.
Dávid Horváth du
2
@ DávidHorváth c'est vraiment bizarre, une bonne pratique à utiliser toujours ===
AFA Med
1
@ DávidHorváth, la comparaison lâche est lâche non seulement en PHP. Si vous regardez JS, vous serez surpris. N'utilisez pas jusqu'à ce que vous compreniez mieux les choses.
ryabenko-pro

Réponses:

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.

Voir Opérateurs de baies .

ÉDITER

L'opérateur d'inégalité est !=alors que l' opérateur de non-identité !==doit correspondre à l'opérateur d'égalité ==et à l'opérateur d'identité ===.

Stefan Gehrig
la source
79
Remarque: cette approche fonctionne également pour les tableaux multidimensionnels (ce n'était pas si évident pour moi auparavant).
trejder
5
PS: la solution est d'utiliser array_values($a)==array_values($b)... Un autre problème habituel concerne les valeurs uniques, alors n'oubliez pas qu'elles existent array_unique().
Peter Krauss du
13
Cette réponse est fausse. ==fonctionne indépendamment de l'ordre uniquement pour les dictionnaires typiques comme [1 => 'a', 2 => 'b']. Par exemple [1 => 'a', 2 => 'b'] == [2 => 'b', 1 => 'a']. Pour les tableaux indexés comme ['a', 'b'] ==ne fonctionne pas comme indiqué. Par exemple ['a', 'b'] != ['b', 'a'].
nawfal
37
@nawfal: Votre hypothèse est fausse. ['a', 'b']est un tableau [0 => 'a', 1 => 'b'], tandis que ['b', 'a']est un tableau [0 => 'b', 1 => 'a']. C'est pourquoi ils n'ont pas les mêmes paires clé / valeur comme indiqué dans ma réponse et c'est pourquoi ==ne fonctionne pas entre ceux-ci.
Stefan Gehrig du
29
@StefanGehrig oh vous avez raison. Je laisserai mon commentaire en tant que tel pour rendre ma folie évidente :)
nawfal
88

Selon cette page .

REMARQUE: la réponse acceptée fonctionne pour les tableaux associatifs, mais elle ne fonctionnera pas comme prévu avec les tableaux indexés (expliqués ci-dessous). Si vous souhaitez comparer l'un ou l'autre, utilisez cette solution. En outre, cette fonction peut ne pas fonctionner avec les tableaux multidimensionnels (en raison de la nature de la fonction array_diff).

Test de deux tableaux indexés, dont les éléments sont dans un ordre différent, en utilisant $a == $bou $a === $béchoue, par exemple:

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

C'est parce que ce qui précède signifie:

array(0 => "x", 1 => "y")par rapport à array(0 => "y", 1 => "x").

Pour résoudre ce problème, utilisez:

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

La comparaison des tailles de tableau a été ajoutée (suggérée par super_ton) car elle peut améliorer la vitesse.

lepe
la source
2
Attention: ne fonctionne pas comme prévu avec les tableaux multidimensionnels
maersu
8
Le commentaire ci-dessus est faux. Si $ b a tous les éléments que $ a a plus quelques éléments supplémentaires, les deux tableaux ne sont pas égaux mais le code ci-dessus le dira.
Ghola
1
pourrait valoir la peine d'ajouter le nombre ($ a) == le nombre ($ b) aussi
Stefan
1
@super_ton: oui, avant d'appeler array_diffpourrait accélérer la comparaison. Je vais l'ajouter. Merci
lepe
3
Malheureusement, cela ne fonctionne pas dans certains cas, par exemple, j'ai testé avec le cas suivant $a = [1, 2, 2]; $b = [2, 1, 1];et il est revenu true, mais les deux tableaux ne sont évidemment pas les mêmes.
AwesomeGuy
33

Essayez de sérialiser. Cela vérifiera également les sous-réseaux imbriqués.

$foo =serialize($array_foo);
$bar =serialize($array_bar);
if ($foo == $bar) echo "Foo and bar are equal";
Iggi
la source
7
Problématique si les clés et les valeurs sont déplacées comme pour la comparaison. Cependant, en supposant qu'ils devraient être identiques à 100%, c'est le moyen le plus propre et le plus simple de vérifier une profonde égalité!
Kevin Peno
1
Je suppose que c'est la meilleure solution! Il peut comparer des tableaux multidimensionnels et associatifs s'ils ont été préalablement triés!
Rafael Moni
13

Solution courte qui fonctionne même avec des tableaux dont les clés sont données dans un ordre différent:

public static function arrays_are_equal($array1, $array2)
{
    array_multisort($array1);
    array_multisort($array2);
    return ( serialize($array1) === serialize($array2) );
}
Samuel Vicent
la source
3
Probablement la meilleure réponse jusqu'à présent, la plupart des réponses ne correspondent pas si les clés sont décalées ou s'il s'agit d'un tableau multidimensionnel.
AwesomeGuy
11

Comparez-les avec d'autres valeurs:

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

Vous pouvez lire sur tous les opérateurs de tableau ici: http://php.net/manual/en/language.operators.array.php Notez par exemple que cela ===vérifie également que les types et l'ordre des éléments dans les tableaux sont les mêmes.

Emil Vikström
la source
5
Ou en ===fonction du comportement souhaité.
Matthew Flaschen
9

!===ne fonctionnera pas car il s'agit d'une erreur de syntaxe. La bonne façon est !==(pas trois symboles "égaux à")

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

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

De mon point de vue, il est préférable d'utiliser array_diff que array_intersect car avec des vérifications de cette nature, les différences retournées sont généralement inférieures aux similitudes, de cette façon la conversion booléenne est moins gourmande en mémoire.

Modifier Notez que cette solution est pour les tableaux simples et complète celle == et === publiée ci-dessus qui n'est valable que pour les dictionnaires.

Marcos Fernandez Ramos
la source
4

array_diff - Calcule la différence des tableaux

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

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

Compare array1avec un ou plusieurs autres tableaux et renvoie les valeurs array1qui ne sont présentes dans aucun des autres tableaux.

Scherbius.com
la source
4
L'OP veut "vérifier si deux tableaux sont égaux". array_diffne peux pas vous le dire. Essayez array_diff([1, 2], [1, 2, 'hello']).
marcv
3

Une autre méthode pour vérifier l'égalité indépendamment de l'ordre des valeurs fonctionne en utilisant http://php.net/manual/en/function.array-intersect.php , comme ceci:

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

Voici une version qui fonctionne également avec des tableaux multidimensionnels utilisant 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;
}
sourcils blancs
la source
3
function compareIsEqualArray(array $array1,array $array):bool
{

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

}
dılo sürücü
la source
2
Il est utile d'expliquer ce que fait un exemple de code. Cela fonctionne-t-il également pour les tableaux multidimensionnels?
k0pernikus
1
array_diff récupère un élément différent du tableau si array_diff retourne un tableau vide le tableau deux est égal
dılo sürücü
2

Une façon: (implémenter «considéré comme égal» pour http://tools.ietf.org/html/rfc6902#section-4.6 )

De cette façon, les tableaux associatifs dont les membres sont classés différemment - par exemple, ils seraient considérés comme égaux dans toutes les langues, mais 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
la source
1
Je crois que ça devrait être:$a[$key] = rksort($a[$key]);
pinkeen le
2

Problème de syntaxe sur vos tableaux

$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
la source
2

Voici l'exemple comment comparer aux tableaux et obtenir ce qui est différent entre eux.

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

Résultat:

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
la source
1

Utilisez la fonction php array_diff (array1, array2);

Il retournera la différence entre les tableaux. Si c'est vide, ils sont égaux.

exemple:

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

Exemple 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
la source
1
Techniquement, il ne renvoie pas la différence entre les tableaux. La documentation indique "compare array1 à un ou plusieurs autres tableaux et renvoie les valeurs de array1 qui ne sont présentes dans aucun des autres tableaux.". Donc, si toutes les valeurs de array1 sont présentes dans array2, même si array2 a plus de valeurs, array_diff retournera un tableau vide
2pha
N'imprime pas "null", imprime un tableau vide (après correction d'une dizaine d'erreurs de syntaxe). Vous pourriez peut-être utiliser (count(array_diff($a1, $a2)) + count(array_diff($a2, $a1))) === 0pour tester si les tableaux sont "égaux"
user9645
J'ai corrigé la syntaxe (non null est vide, et je mixais des virgules -.-). Je pense que ce que vous proposez est trop. Vérifier si c'est un tableau vide devrait suffire.
Wolfgang Leon
1

Si vous souhaitez vérifier les tableaux non associatifs, voici la solution:

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

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