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, вы будете удивлены. Просто не используйте, пока не поймете вещи лучше.
— рябенко-про

Ответы:


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.

Смотрите Операторы Массива .

РЕДАКТИРОВАТЬ

Оператор неравенства - это, в !=то время как неединичный оператор !==должен соответствовать оператору равенства ==и тождественному оператору ===.


79
Примечание: этот подход работает и для многомерных массивов (раньше это не было так очевидно для меня).
— Трейдер

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")против 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
Внимание: не работает
— должным образом

8
Приведенный выше комментарий является ложным. Если $ b имеет все элементы, которые имеет $ a, плюс некоторые дополнительные, два массива не равны, но приведенный выше код скажет, что они есть.
— Гхола

1
возможно, стоит добавить счетчик ($ a) == счетчик ($ b)
— Стефан

1
@super_ton: да, перед звонком array_diffможно было бы ускорить сравнение. Я добавлю это. Спасибо
— Лепе

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
Я думаю, это лучшее решение! Он может сравнивать многомерные и ассоциативные массивы, если они были ранее отсортированы!
— Рафаэль Мони

14

Краткое решение, которое работает даже с массивами, ключи которых даны в другом порядке:

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

3
Вероятно, лучший ответ до сих пор, большинство ответов либо не совпадают, если ключи смещены, или это многомерный массив.
— AwesomeGuy

Хороший выбор! Но обратите внимание, что этот метод использует строгое сравнение типов, поэтому, если вы хотите сравнить [1,2,3] и ['1', '2', '3'], результат будет ложным.
— ChronoExp

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']).
— марта

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, которых нет ни в одном из других массивов». Итак, если все значения из array1 присутствуют в array2, даже если 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.