Определить, имеют ли 2 ассоциативных массива одинаковое содержимое

#php #arrays #comparison

#php #массивы #сравнение

Вопрос:

Я пытаюсь создать PHP-функцию, которая сравнивает 2 массива и возвращает true, если они идентичны.

Пример:

 assertArrayEquals(array('a'=>1, 'b'=>2), array('a'=>1, 'b'=>2)); // True
assertArrayEquals(array('a'=>1, 'b'=>2), array('b'=>2, 'a'=>1)); // True
assertArrayEquals(array('a'=>1, 'b'=>2), array(1, 2)); // false
assertArrayEquals(array(2, 1), array(1, 2)); // false
  

Есть идеи?

Редактировать: Другие примеры тестов:

 assertArrayEquals(array('a'=>1, 'b'=>2), array('a'=>1, 'b'=>2, 'c'=>3)); // false
assertArrayEquals(array('a'=>1, 'b'=>2, 'c'=>3), array('a'=>1, 'b'=>2)); // false
assertArrayEquals(array('a'=>0), array('a'=>'foo')); // false
  

Комментарии:

1. Не будет == ли это работать достаточно хорошо для вас?

2. Nop, поскольку == выполняется только проверка значений (как это сделал бы array_diff ), случай # 3 прошел бы.

3. @FMaz008, Случай # 3 не проходит с == . Я протестировал это.

4. Тогда все 4 пройдут ( поскольку предполагается, что функция array_diff не проверяет ассоциацию ключей, такую как array_diff_assoc )

5. Пожалуйста, проверьте руководство ( операторы массива ), прежде чем делать предположения: » $ a == $b — Равенство — TRUE, если $ a и $ b имеют одинаковые пары ключ / значение . » Пример 4 также не пройдет, поскольку пары ключ / значение не совпадают: 0 => 2, 1 => 1 vs 0 => 1, 1 => 2 .

Ответ №1:

Используйте array_diff_assoc:

 <?php

var_dump(assertArrayEquals(array('a'=>1, 'b'=>2), array('a'=>1, 'b'=>2))); // True
var_dump(assertArrayEquals(array('a'=>1, 'b'=>2), array('b'=>2, 'a'=>1))); // True
var_dump(assertArrayEquals(array('a'=>1, 'b'=>2), array(1, 2))); // false
var_dump(assertArrayEquals(array(2, 1), array(1, 2))); // false



function assertArrayEquals($a, $b){
  return count(array_diff_assoc($a,$b)) == 0 amp;amp; count(array_diff_assoc($b,$a)) == 0;
}
  

http://codepad.org/YoZIGjBY

Комментарии:

1. Кажется, это хорошая функция, я проведу модульное тестирование и вернусь 🙂

2. Этот проход и он должен завершиться ошибкой: array(‘a’=> 1, ‘b’=> 2), array(‘a’=>1, ‘b’=>2, ‘c’=>3)

3. Совершенно верно, позвольте мне переписать это.

4. С идеей Чарли Пиги я придумал: возвращать count(array_diff_assoc($ a, $ b)) == 0 amp;amp; count(array_diff_assoc($ b, $ a)) == 0;, но, возможно, можно сделать что-то лучше.

Ответ №2:

проверьте http://php.net/array_diff и http://php.net/array_intersect

Или все, что вы можете сделать, это проверить равенство:

отсортируйте оба массива и проверьте с помощью === (или ==, если вы пугливый котенок)

Комментарии:

1. === не будет утверждать второй случай. == будет заботиться только о значениях, одинаковых для array_diff / intersect.

Ответ №3:

Используйте == .

Руководство по php: операторы массива:

$a == $b — Равенство — TRUE, если $ a и $ b имеют одинаковые пары ключ / значение.


Пример 4 не пройдет, поскольку пары ключ / значение не совпадают:

0 => 2, 1 => 1 против 0 => 1, 1 => 2 .


Редактировать:

Если массивы содержат разные типы переменных, используйте

 function assertArrayEquals($a, $b) {
  asort($a);
  asort($b);

  return $a === $b;
}
  

Это даст ожидаемые результаты даже для примера в комментарии:

 echo (int)assertArrayEquals(array('a'=>1, 'b'=>2),  array('a'=>1, 'b'=>2));     // true
echo (int)assertArrayEquals(array('a'=>1, 'b'=>2),  array('b'=>2, 'a'=>1));     // true
echo (int)assertArrayEquals(array('a'=>1, 'b'=>2),  array(1, 2));               // false
echo (int)assertArrayEquals(array(2, 1),            array(1, 2));               // false
echo (int)assertArrayEquals(array('a'=>0,'b'=>1),   array('a'=>'cake','b'=>1)); // false
echo (int)assertArrayEquals(array('a'=>'0','b'=>1), array('a'=>'cake','b'=>1)); // false
  

Комментарии:

1. array('a'=>0,'b'=>1) == array('a'=>'cake','b'=>1) выдает неверный результат для нужд FMaz008.

2. Для этого тестового примера я бы ожидал false, а не true … : (

3. Да, это произойдет, потому что 0=='cake' . С другой стороны, array('a'=>'0','b'=>1) == array('a'=>'cake','b'=>1) вернет false (обратите внимание на кавычки вокруг нуля). Но вы могли бы сортировать и сравнивать, используя === — см. Мой отредактированный ответ.

4. @salathe, зависит от приложения. Я думаю, что в большинстве приложений значения с одинаковыми ключами, вероятно, будут иметь одинаковый тип. Если нет, то более позднее решение лучше…

Ответ №4:

Похоже, вы хотите убедиться, что массивы имеют одинаковые пары ключ / значение (строго типизированные), но не обязательно в одинаковом порядке. Итак, сделайте заказы согласованными и строго сравните их.

 function assertArrayEquals($a, $b)
{
    ksort($a); ksort($b);
    return ($a === $b);
}
  

Путем тестирования,

 testAssertArrayEquals(array('a'=>1, 'b'=>2),         array('a'=>1, 'b'=>2),         true);
testAssertArrayEquals(array('a'=>1, 'b'=>2),         array('b'=>2, 'a'=>1),         true);
testAssertArrayEquals(array('a'=>1, 'b'=>2),         array(1, 2),                   false);
testAssertArrayEquals(array(2, 1),                   array(1, 2),                   false);
testAssertArrayEquals(array('a'=>1, 'b'=>2),         array('a'=>1, 'b'=>2, 'c'=>3), false);
testAssertArrayEquals(array('a'=>1, 'b'=>2, 'c'=>3), array('a'=>1, 'b'=>2),         false);
testAssertArrayEquals(array('a'=>0,'b'=>1),          array('a'=>'cake','b'=>1),     false); // Extra

function testAssertArrayEquals($a, $b, $expected)
{
    $result = assertArrayEquals($a, $b);
    echo "Got " . var_export($result,1) . " expected " . var_export($expected,1) . PHP_EOL;
}

// Got true expected true
// Got true expected true
// Got false expected false
// Got false expected false
// Got false expected false
// Got false expected false
// Got false expected false
  

Я бы также посоветовал выбрать лучшее имя функции, ваш текущий выбор не принесет вам никакой пользы в долгосрочной перспективе!

Ответ №5:

В PHP есть функция для этого.

 $result = array_diff($array1, $array2);
  

$result вернет все, что отличается в массивах. Если они совпадают, это ничего не вернет.

Комментарии:

1. Не заботится о ключах.

Ответ №6:

 function assertArrayEquals($array1, $array2) {
  return !array_diff($array1, $array2) and !array_diff($array2, $array1);
}
  

В основном мы используем array_diff(), чтобы проверить, есть ли какая-либо разница между двумя заданными массивами. Если нет, то они равны.

Несмотря на эту чистую форму, вы могли бы использовать simple == для сравнения двух массивов. Вот несколько протестированных примеров:

 echo (array('a'=>1, 'b'=>2) == array('a'=>1, 'b'=>2)) ? 'true' : 'false'; // true
echo (array('a'=>1, 'b'=>2) == array('b'=>2, 'a'=>1)) ? 'true' : 'false'; // true
echo (array('a'=>1, 'b'=>2) == array(1, 2)) ? 'true' : 'false'; // false
echo (array(2, 1) == array(1, 2)) ? 'true' : 'false'; // false
  

Вывод этого скрипта: truetruefalsefalse ;

Комментарии:

1. Не удается утверждать, что array(‘a’=>1, ‘b’=>2), array(‘b’=>1, ‘a’=>2) равно false.

2. Должно было быть false, поскольку значения ключа были заменены.