web-dev-qa-db-fra.com

PHP comparer le tableau

Est-il possible de comparer des tableaux en php en utilisant une fonction intégrée, à moins de faire une sorte de boucle?

$a1 = array(1,2,3);
$a2 = array(1,2,3);

if (array_are_same($a1, $a2)) {
    // code here
}

Btw, les valeurs du tableau ne seront pas toujours dans le même ordre.

27
Andy Morcam
if ( $a == $b ) {
    echo 'We are the same!'
}
36

La comparaison de deux tableaux pour avoir des valeurs égales (dupliquées ou non, en tenant compte du type) peut être effectuée en utilisant array_diff() dans les deux sens:

!array_diff($a, $b) && !array_diff($b, $a);

Cela donne TRUE si les deux tableaux ont les mêmes valeurs (après avoir jonglé avec le type). FALSE sinon. Exemples:

function array_equal_values(array $a, array $b) {
    return !array_diff($a, $b) && !array_diff($b, $a);
}

array_equal_values([1], []);            # FALSE
array_equal_values([], [1]);            # FALSE
array_equal_values(['1'], [1]);         # TRUE
array_equal_values(['1'], [1, 1, '1']); # TRUE

Comme le montre cet exemple, array_diff Laisse les clés de tableau hors de l'équation et ne se soucie pas non plus de l'ordre des valeurs ni de la duplication ou non des valeurs.


Si la duplication doit faire la différence, cela devient plus délicat. En ce qui concerne les valeurs "simples" (seules les chaînes et les entiers fonctionnent), array_count_values() entre en jeu pour recueillir des informations sur la valeur correspondant à la fréquence à l'intérieur d'un tableau. Ces informations peuvent être facilement comparées à ==:

array_count_values($a) == array_count_values($b);

Cela donne TRUE si les deux tableaux ont les mêmes valeurs (après avoir jonglé avec le type) pendant la même durée. FALSE sinon. Exemples:

function array_equal_values(array $a, array $b) {
    return array_count_values($a) == array_count_values($b);
}

array_equal_values([2, 1], [1, 2]);           # TRUE
array_equal_values([2, 1, 2], [1, 2, 2]);     # TRUE
array_equal_values(['2', '2'], [2, '2.0']);   # FALSE
array_equal_values(['2.0', '2'], [2, '2.0']); # TRUE

Cela peut être encore optimisé en comparant d'abord le nombre des deux tableaux, ce qui est relativement bon marché et un test rapide pour distinguer la plupart des tableaux lorsque le comptage de duplication de valeur fait une différence.


Jusqu'à présent, ces exemples sont partiellement limités aux chaînes et aux valeurs entières et aucune comparaison stricte n'est possible avec array_diff Non plus. Plus dédié à la comparaison stricte est array_search . Les valeurs doivent donc être comptées et indexées pour pouvoir être comparées, car il suffit de les transformer en clé (comme le fait array_search).

C'est un peu plus de travail. Cependant, au final, la comparaison est la même que précédemment:

$count($a) == $count($b);

C'est juste $count Qui fait la différence:

    $table = [];
    $count = function (array $array) use (&$table) {
        $exit   = (bool)$table;
        $result = [];
        foreach ($array as $value) {
            $key = array_search($value, $table, true);

            if (FALSE !== $key) {
                if (!isset($result[$key])) {
                    $result[$key] = 1;
                } else {
                    $result[$key]++;
                }
                continue;
            }

            if ($exit) {
                break;
            }

            $key          = count($table);
            $table[$key]  = $value;
            $result[$key] = 1;
        }

        return $result;
    };

Cela conserve une table de valeurs afin que les deux tableaux puissent utiliser le même index. Il est également possible de quitter tôt la première fois dans le deuxième tableau une nouvelle valeur est expérimentée.

Cette fonction peut également ajouter le contexte strict en ayant un paramètre supplémentaire. Et en ajoutant un autre paramètre supplémentaire, cela permettrait d'activer ou non la recherche de doublons. L'exemple complet:

function array_equal_values(array $a, array $b, $strict = FALSE, $allow_duplicate_values = TRUE) {

    $add = (int)!$allow_duplicate_values;

    if ($add and count($a) !== count($b)) {
        return FALSE;
    }

    $table = [];
    $count = function (array $array) use (&$table, $add, $strict) {
        $exit   = (bool)$table;
        $result = [];
        foreach ($array as $value) {
            $key = array_search($value, $table, $strict);

            if (FALSE !== $key) {
                if (!isset($result[$key])) {
                    $result[$key] = 1;
                } else {
                    $result[$key] += $add;
                }
                continue;
            }

            if ($exit) {
                break;
            }

            $key          = count($table);
            $table[$key]  = $value;
            $result[$key] = 1;
        }

        return $result;
    };

    return $count($a) == $count($b);
}

Exemples d'utilisation:

array_equal_values(['2.0', '2', 2], ['2', '2.0', 2], TRUE);           # TRUE
array_equal_values(['2.0', '2', 2, 2], ['2', '2.0', 2], TRUE);        # TRUE
array_equal_values(['2.0', '2', 2, 2], ['2', '2.0', 2], TRUE, FALSE); # FALSE
array_equal_values(['2'], ['2'], TRUE, FALSE);                        # TRUE
array_equal_values([2], ['2', 2]);                                    # TRUE
array_equal_values([2], ['2', 2], FALSE);                             # TRUE
array_equal_values([2], ['2', 2], FALSE, TRUE);                       # FALSE
28
hakre

@Cleanshooter je suis désolé mais cela ne fait pas ce que l'on attend de lui: (tout comme array_diff mentionné dans ce contexte)

$a1 = array('one','two');
$a2 = array('one','two','three');

var_dump(count(array_diff($a1, $a2)) === 0); // returns TRUE

(annotation: vous ne pouvez pas utiliser vide sur les fonctions avant PHP 5.5 ) dans ce cas, le résultat est vrai même si les tableaux sont différents.

array_diff [...] Renvoie un tableau contenant toutes les entrées de array1 qui ne sont présentes dans aucun des autres tableaux.

ce qui ne signifie pas que array_diff est quelque chose comme: array_get_all_differences. Expliqué dans des ensembles mathématiques, il calcule:

{'one','two'} \ {'one','two','three'} = {}

ce qui signifie quelque chose comme tous les éléments du premier ensemble sans tous les éléments du deuxième ensemble, qui sont dans le premier ensemble. Pour que

var_dump(array_diff($a2, $a1));

calcule à

array(1) { [2]=> string(5) "three" } 

La conclusion est que vous devez faire un array_diff dans "les deux sens" pour obtenir toutes les "différences" des deux tableaux.

j'espère que cela t'aides :)

12
P.Scheit

Vous pouvez également essayer de cette façon:

if(serialize($a1) == serialize($a2))
4
Murz

array_intersect() renvoie un tableau contenant toutes les valeurs communes.

3
moonw

Vérifiez simplement $a1 == $a2 -- Qu'est-ce qui ne va pas avec ça?

3
Alex Martelli

obtenir le tableau de l'utilisateur ou entrer les valeurs du tableau. Utilisez la fonction de tri pour trier les deux tableaux. vérifier en utilisant l'opérateur ternaire. Si les deux tableaux sont égaux, il imprimera les tableaux sont égaux, sinon il imprimera les tableaux ne sont pas égaux. il n'y a pas d'itération de boucle ici.

sort($a1);
sort($a2);
echo (($a1==$a2) ? "arrays are equal" : "arrays are not equal");
1
CJ Ramki

Une méthode rapide pour comparer les valeurs de tableau qui peuvent être dans n'importe quel ordre ...

function arrays_are_same($array1, $array2) {
    sort($array1);
    sort($array2);
    return $array1==$array2;
}

Donc pour...

    $array1 = array('audio', 'video', 'image');
    $array2 = array('video', 'image', 'audio');

arrays_are_same($array1, $array2) renverra TRUE

1
chichilatte

Conclusion du commentaire ici:

Comparaison des valeurs du tableau étant égales (après jonglage de type) et dans le même ordre uniquement:

array_values($a1) == array_values($a2)

Comparaison des valeurs de tableau étant égales (après jonglage de type) et dans le même ordre et les clés de tableau étant les mêmes et dans le même ordre:

array_values($a1) == array_values($a2) && array_keys($a1) == array_keys($a2)
1
Tyron

vérifier que le nombre d'intersections est le même que les deux tableaux source

$intersections = array_intersect($a1, $a2);
$equality = (count($a1) == count($a2)) && (count($a2) == count($intersections)) ? true : false;
0
rcourtna

Si vous souhaitez rechercher un tableau à l'intérieur n grand tablea de tableaux (> 10k) alors beaucoup plus rapidement compare les tableaux sérialisés (enregistrés dans le cache). Exemple de travail avec URL:

/**
@return array
*/
function createCache()
{
    $cache = [];
    foreach ($this->listOfUrl() as $url => $args)
    {
        ksort($args);
        $cache['url'][$url] = $args;
        $cache['arr'][crc32(serialize($args))] = $url;
    }
    return $cache;
}

/**
@param array $args
@return string
*/
function searchUrl($args)
{
    ksort($params);
    $crc = crc32(serialize($params));        
    return isset($this->cache['arr'][$crc]) ? $this->cache['arr'][$crc] : NULL;                
} 

/**
@param string $url
@return array
*/
function searchArgs($url)
{
    return isset($this->cache['url'][$url]) ? $this->cache['url'][$url] : NULL;
}
0
revoke

Si vous ne vous souciez pas des clés et que seules les valeurs sont la meilleure méthode pour comparer les valeurs et vous assurer que les doublons sont comptés.

$mag = '{"1":"1","2":"2","3":"3","4":"3"}';
$mag_evo = '1|2|3';

$test1 = array_values(json_decode($mag, true));
$test2 = array_values(explode('|', $mag_evo));

if($test1 == $test2) {
    echo 'true';
}

Cela ne fera pas écho vrai car $ mag a 2 valeurs dans le tableau égales à 3.

Cela fonctionne mieux si vous ne vous souciez que des valeurs et des clés et que vous ne vous souciez pas de la duplication. $ mag = '{"1": "1", "2": "2", "3": "3", "4": "3"}'; $ mag_evo = '1 | 2 | 3';

$test1 = json_decode($mag, true);
$test2 = explode('|', $mag_evo);

// There is no difference in either array.  
if(!array_diff($test1, $test2) && !array_diff($test2, $test1)) { 
    echo 'true';
}

Cela retournera vrai car toutes les valeurs se trouvent dans les deux tableaux, mais comme indiqué précédemment, il ne se soucie pas de la duplication.

0
Case

Comparez les valeurs de deux tableaux:

$a = array(1,2,3);
$b = array(1,3,2);

if (array_diff($a, $b) || array_diff($b, $a)) {
    echo 'Not equal';
}else{
    echo 'Equal';
}
0
1Rhino