PHP: встроенная функция, чтобы проверить, равны ли два значения массива (игнорируя порядок)

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

Например, я хочу функцию, которая возвращает мне true для следующих двух входов:

array('4','5','2') 
array('2','4','5')

Редактировать: я мог бы отсортировать два массива и сравнить их, но, поскольку я такой ленивый парень, я все равно предпочел бы одну строку, которую я могу вытащить и использовать.

8 ответов

Решение

array_diff выглядит как опция:

function array_equal($a1, $a2) {
  return !array_diff($a1, $a2) && !array_diff($a2, $a1);
}

или как подписчик в вашем коде:

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

Но это имеет сложность O(n^ 2). Поэтому вам лучше использовать метод сортировки.

array_diff() Метод выше не будет работать.

Руководство php.net говорит, что array_diff() Является ли это:

Msgs tr "Возвращает массив, содержащий все записи из array1, которых нет ни в одном из других массивов."

Так актуально 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
}

В дополнение к принятому ответу от @knittl

Чтобы покрыть случай, когда один из массивов имеет дополнительные элементы:

      function areEqualIfOrderIgnored(array $a1, array $a2): bool
{
    if (
        ! array_diff($a1, $a2)
        && ! array_diff($a2, $a1)
        && count($a1) === count($a2)
    ) {
        return true;
    }

    return false;
}

Или одну строку, как просили (но некрасиво)

      if (! array_diff($a1, $a2) && ! array_diff($a2, $a1) && count($a1) === count($a2)) {do smth}

Если сравниваемые массивы состоят только из строк и / или целых чисел, array_count_values позволяет быстро сравнивать массивы (в O(n) время против O(n log n) для сортировки) путем проверки того, что оба массива содержат одинаковые значения и что каждое значение встречается в обоих массивах одинаково # раз.

if(array_count_values($a1) == array_count_values($a2)) {
    //arrays are equal
}

Ты можешь использовать 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() это быстро.
  • чем больше массивов (больше 10 значений), тем больше array_intersect() это быстро.

В зависимости от этих факторов один метод может быть в два-три раза быстрее другого. Для больших массивов с несколькими (или без) совпадающих комбинаций или для маленьких массивов с большим количеством совпадений оба метода эквивалентны.

Однако метод сортировки всегда быстрее, за исключением случая с небольшими массивами с небольшим количеством или без совпадений комбинаций. В этом случае array_diff() метод на 30% быстрее.

Другие вопросы по тегам