Есть ли встроенная функция для PHP, чтобы проверить, содержат ли два массива одинаковые значения (порядок не важен?).
Например, я хочу функцию, которая возвращает меня true для следующих двух входов:
array('4','5','2') array('2','4','5')
Edit: Я мог бы отсортировать два массива и сравнить их, но поскольку я такой ленивый парень, я бы предпочел один лайнер, который я могу вытащить и использовать.
array_diff выглядит как опция:
function array_equal($a1, $a2) { return !array_diff($a1, $a2) && !array_diff($a2, $a1); }
или как oneliner в вашем коде:
if(!array_diff($a1, $a2) && !array_diff($a2, $a1)) doSomething();
Лучшим решением является сортировка обоих массивов, а затем их сравнение:
$a = array('4','5','2'); $b = array('2','4','5'); sort($a); sort($b); var_dump($a === $b);
Как функция:
function array_equal($a, $b, $strict=false) { if (count($a) !== count($b)) { return false; } sort($a); sort($b); return ($strict && $a === $b) || $a == $b; }
Вот еще один алгоритм, который ищет каждый элемент A, если он находится в B :
function array_equal($a, $b, $strict=false) { if (count($a) !== count($b)) { return false; } foreach ($a as $val) { $key = array_search($val, $b, $strict); if ($key === false) { return false; } unset($b[$key]); } return true; }
сfunction array_equal($a, $b, $strict=false) { if (count($a) !== count($b)) { return false; } foreach ($a as $val) { $key = array_search($val, $b, $strict); if ($key === false) { return false; } unset($b[$key]); } return true; }
Но это имеет сложность O ( n ^ 2). Поэтому вам лучше использовать метод сортировки.
Метод array_diff()
выше не будет работать.
Руководство php.net говорит, что array_diff()
делает это:
«Возвращает массив, содержащий все записи из массива1, которые не присутствуют ни в одном из других массивов».
Таким образом, фактический array_diff()
будет:
function array_equal($array1, $array2) { $diff1 = array_diff($array1, $array2); $diff2 = array_diff($array2, $array1); return ( (count($diff1) === 0) && (count($diff2) === 0) ); }
Однако я использую метод сортировки: D
Вы можете использовать array_diff.
$a = array('4','5','2'); $b = array('2','4','5'); if(count(array_diff($a, $b)) == 0) { // arrays contain the same elements } else { // arrays contain different elements }
Однако проблема с этим подходом заключается в том, что массивы могут содержать повторяющиеся элементы и по-прежнему совпадают.
Вам нужно всего лишь сравнить однонаправленное использование array_diff()
и использовать count()
для инвертированного отношения.
if (count($a1) == count($a2) && !array_diff($a1, $a2)) { // equal arrays }
Вы можете использовать array_intersect()
вместо array_diff()
:
$a = array('4','5','2'); $b = array('2','4','5'); $ca = count($a); $cb = count($b); $array_equal = ( $ca == $cb && $ca == count(array_intersect($a, $b)) );
Эффективность. решение, где важны два фактора:
array_intersect()
выполняется быстро. array_intersect()
работает быстро. В зависимости от этих факторов один метод может быть в два-три раза быстрее, чем другой. Для больших массивов с небольшими (или нет) комбинациями соответствия или для небольших массивов с большим количеством совпадений оба метода эквивалентны.
Тем не менее метод сортировки всегда быстрее, за исключением случаев с небольшими массивами с небольшим количеством комбинаций или без них. В этом случае метод array_diff()
30% быстрее.
Если сопоставляемые массивы состоят только из строк и / или целых чисел, array_count_values
позволяет быстро сравнивать массивы (в O(n)
время против O(n log n)
), проверяя, что оба массива содержат одинаковые значения, и что каждое значение имеет одно и то же число раз в обоих массивах.
if(array_count_values($a1) == array_count_values($a2)) { //arrays are equal }