PHP - Перевірте, чи два масиви рівні


280

Я хотів би перевірити, чи рівні два масиви. Я маю на увазі: той самий розмір, той же індекс, ті ж значення. Як я можу це зробити?

Використання !==як запропоновано користувачем, я очікую , що наступний буде друкувати ввести , якщо хоча б один елемент масиву (ів) різні, але насправді це не так.

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

    echo "enter";
}

17
Ви використовуєте =занадто багато, це повинно бути !==або!=
jeroen

29
Тільки для запису (так як мої редагувати переодяглися назад в «користувач») це «користувач»: english.stackexchange.com/questions/105116 / ...
teynon

7
['a'] == [0]є true. Ну, це просто PHP.
Давид Хорват

2
@ DávidHorváth це дійсно дивно, хороша практика використовувати його завжди ===
AFA Med

1
@ DávidHorváth, вільне порівняння є вільним не лише в PHP. Якщо ви подивитесь на JS, ви здивуєтеся. Просто не використовуйте, поки не зрозумієте щось краще.
рябенько-про

Відповіді:


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.

Див. Оператори масиву .

EDIT

Оператор нерівності - це !=той час, коли оператор неідентичності !==повинен відповідати оператору рівності ==та оператору ідентичності ===.


79
Побічна примітка: Цей підхід працює і для багатовимірних масивів (для мене це не було очевидно раніше).
trejder

5
PS: рішенням є використання array_values($a)==array_values($b)... Ще одна звичайна проблема - це унікальні значення, тому пам’ятайте, що вони існують array_unique().
Пітер Краусс

13
Ця відповідь неправильна. ==працює незалежно від порядку лише для типових словників типу [1 => 'a', 2 => 'b']. Наприклад, наприклад [1 => 'a', 2 => 'b'] == [2 => 'b', 1 => 'a']. Для індексованих масивів типу ['a', 'b'] ==не працює, як зазначено. Наприклад, наприклад ['a', 'b'] != ['b', 'a'].
nawfal

37
@nawfal: Ваше припущення неправильне. ['a', 'b']- це масив [0 => 'a', 1 => 'b'], а ['b', 'a']масив [0 => 'b', 1 => 'a']. Ось чому вони не мають тих самих пар ключів / значень, як зазначено в моїй відповіді, і тому ==між ними не працює.
Стефан Гегріг

29
@StefanGehrig о, ти правий. Я залишу свій коментар як такий, щоб зробити свою дурість очевидною :)
nawfal

88

Відповідно до цієї сторінки .

ПРИМІТКА . Прийнята відповідь працює для асоціативних масивів, але вона не працюватиме, як очікувалося, для індексованих масивів (пояснено нижче). Якщо ви хочете порівняти будь-який з них, тоді використовуйте це рішення. Крім того, ця функція може не працювати з багатовимірними масивами (через характер функції array_diff).

Тестування двох індексованих масивів, елементи яких у різному порядку, використовуючи $a == $bабо$a === $b відмовляються, наприклад:

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

Це тому, що вищезазначене означає:

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

Щоб вирішити цю проблему, використовуйте:

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

Додано порівняння розмірів масиву (запропоновано super_ton), оскільки це може підвищити швидкість.


2
Увага: не працює так, як очікувалося, для багатовимірних масивів
maersu

8
Наведений коментар хибний. Якщо у $ b є всі елементи $ a має додаткові додаткові, два масиви не рівні, але вищевказаний код скаже, що вони є.
Ghola

1
можливо, варто додати count ($ a) == count ($ b) теж
stefan

1
@super_ton: так, перед викликом array_diffможна пришвидшити порівняння. Я додам його. Дякую
lepe

3
На жаль, це не працює в деяких випадках, наприклад, я перевірив наступний випадок, $a = [1, 2, 2]; $b = [2, 1, 1];і він повернувся true, але два масиви, очевидно, не однакові.
AwesomeGuy

33

Спробуйте серіалізувати. Це також перевірить вкладені підрядні масиви.

$foo =serialize($array_foo);
$bar =serialize($array_bar);
if ($foo == $bar) echo "Foo and bar are equal";

7
Проблематично, якщо ключі та значення зміщуються навколо так само, як і для порівняння. Однак, якщо припустити, що вони будуть на 100% однаковими, це найчистіший і найпростіший спосіб перевірити глибоку рівність!
Кевін Пено

1
Я думаю, це найкраще рішення! Він може порівнювати багатовимірні та асоціативні масиви, якщо вони раніше були відсортовані!
Рафаель Моні

13

Коротке рішення, яке працює навіть з масивами, клавіші яких задані в різному порядку:

public static function arrays_are_equal($array1, $array2)
{
    array_multisort($array1);
    array_multisort($array2);
    return ( serialize($array1) === serialize($array2) );
}

3
Мабуть, найкраща відповідь поки що, більшість відповідей або не відповідають, якщо клавіші зміщені, або якщо це багатовимірний масив.
AwesomeGuy

11

Порівняйте їх як інші значення:

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

Про всі оператори масиву ви можете прочитати тут: http://php.net/manual/en/language.operators.array.php Примітка, наприклад, що ===також перевіряється, що типи та порядок елементів у масивах однакові.


5
Або ===залежно від бажаної поведінки.
Метью Флашен

9

!===не буде працювати, оскільки це синтаксична помилка. Правильний спосіб !==(не три "рівних" символу)


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

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

З мого pov краще використовувати array_diff, ніж array_intersect, тому що при перевірках такого характеру відмінності, що повертаються, зазвичай менше, ніж подібності, таким чином конверсія bool менше голодна.

Редагування Зауважте, що це рішення призначено для простих масивів і доповнює розміщені вище == та ===, що є дійсним лише для словників.


4

array_diff - обчислює різницю масивів

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

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

Порівнюється array1з одним або декількома іншими масивами та повертає значення array1, які відсутні в жодному з інших масивів.


4
ОП хоче "перевірити, чи два масиви рівні". array_diffне можу тобі це сказати. Спробуйте array_diff([1, 2], [1, 2, 'hello']).
marcv

3

Інший метод перевірки рівності незалежно від порядку замовлення працює за допомогою http://php.net/manual/en/function.array-intersect.php , наприклад:

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

Ось версія, яка також працює з багатовимірними масивами, використовуючи 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
Корисно пояснити, що робить приклад коду. Це також працює для багатовимірних масивів?
k0pernikus

1
array_diff отримати інший елемент від масиву, якщо array_diff поверне порожній масив, два масиви рівні
dılo sürücü

2

Один із способів: (реалізація "вважається рівним" для http://tools.ietf.org/html/rfc6902#section-4.6 )

Цей спосіб дозволяє асоціативні масиви, члени яких впорядковані по-різному - наприклад, їх вважатимуть рівними в усіх мовах, окрім 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
Я вважаю, що вам це повинно бути:$a[$key] = rksort($a[$key]);
pinkeen

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

2

Ось приклад, як порівняти масиви і отримати те, що між ними відрізняється.

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

Результат:

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

        )

    [b] => MISSING IN SECOND
    [1] => DIFFERENT
    [2] => MISSING IN FIRST
)

1

Використовуйте функцію php array_diff (array1, array2);

Це поверне різницю між масивами. Якщо його порожнє, то вони рівні.

приклад:

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

Приклад 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
Технічно це не повертає різниці між масивами. У документації зазначено "Порівняє масив1 проти одного або декількох інших масивів і повертає значення в масиві1, які відсутні в жодному з інших масивів." Отже, якщо в array2 присутні всі значення з array1, навіть якщо array2 має більше значень, array_diff поверне порожній масив
2pha

Не "друкує нуль", друкує порожній масив (після виправлення близько десятка синтаксичних помилок). Можливо, ви могли б використати (count(array_diff($a1, $a2)) + count(array_diff($a2, $a1))) === 0для перевірки, чи масиви "рівні"
user9645

Я виправив синтаксис (не нуль порожній, і я змішував коми -.-). Те, що ти пропонуєш, я думаю, що це занадто багато. Перевірка, чи має бути достатньо порожнього масиву.
Вольфганг Леон

1

Якщо ви хочете перевірити неасоціативні масиви, ось таке рішення:

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

(count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';
// Equals
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.