У меня есть два массива, $ a и $ b здесь, и вам нужно проверить, содержат ли они точно такие же элементы (независимо от порядка). Я думаю использовать
if (sizeof($a)==sizeof($b) AND array_diff($a,$b)==array()) { }
Но я новичок в PHP, поэтому мне интересно: есть ли лучший способ?
Поскольку мне нужно использовать их в качестве наборов, возможно, я не должен использовать массивы вообще, кроме как что-то еще.
Ну, мы можем сделать что-то вроде этого:
if (count(array_diff(array_merge($a, $b), array_intersect($a, $b))) === 0) { //they are the same! }
Причина, по которой он работает, заключается в том, что array_merge
будет создавать большой массив, который имеет все элементы как $a
и $b
(все элементы, которые находятся либо в $a
, $b
, либо в обоих). array_intersect
создаст массив, содержащий все элементы только в $a
и $b
. Поэтому, если они разные, должен быть хотя бы один элемент, который не отображается в обоих массивах …
Также обратите внимание, что sizeof
не является фактической функцией / конструкцией, это псевдоним. Я бы предложил использовать count()
для ясности …
Только для вашего удовольствия я добавлю пример, демонстрирующий, что ваши условия неверны:
<?php $a = array(1, 1, 2); $b = array(1, 2, 3); var_dump(sizeof($a)==sizeof($b) AND array_diff($a,$b)==array()); ?>
Попробуй это.
Я бы предложил использовать другую модель. Возможно, добавление элементов в качестве ключей массива, но это возможно только в том случае, если они являются целыми числами или строками.
$arr['itemA'] = true; $arr['itemB'] = true;
Это обеспечит уникальность. С помощью этой модели вы можете использовать свое условие для array_keys($arr)
.
Если вы думаете о массивах в виде наборов :
Тогда ваш подход почти правильный (вам нужно сбросить тест равенства для подсчета элементов).
Если важно, чтобы массивы содержали несколько копий одного и того же элемента :
Тогда ваш подход неверен. Вам нужно отсортировать массивы с sort
а затем сравнить их с ===
. Это должно быть быстрее, поскольку оно может прервать сравнение в тот момент, когда он видит одно отличие, не обойдя все массивы.
Обновить:
Уточненный точно, когда подход OP был правильным или нет, также было включено предложение о том, что sort
будет, вероятно, лучше, чем здесь.
Принятый ответ неверен! Он не будет работать: https://3v4l.org/U8U5p
$a = ['x' => 1, 'y' => 2]; $b = ['x' => 1, 'y' => 1];
Вот правильное решение:
function consistsOfTheSameValues(array $a, array $b) { // check size of both arrays if (count($a) !== count($b)) { return false; } foreach ($b as $key => $bValue) { // check that expected value exists in the array if (!in_array($bValue, $a, true)) { return false; } // check that expected value occurs the same amount of times in both arrays if (count(array_keys($a, $bValue, true)) !== count(array_keys($b, $bValue, true))) { return false; } } return true; }
Плюс довольно обширные модульные тесты: https://3v4l.org/m6lHv
<?php // A unit testing framework in a tweet. https://gist.github.com/mathiasverraes/9046427 function it($m,$p){echo ($p?'✔︎':'✘')." It $m\n"; if(!$p){$GLOBALS['f']=1;}}function done(){if(@$GLOBALS['f'])die(1);} function consistsOfTheSameValues(array $a, array $b) { // check size of both arrays if (count($a) !== count($b)) { return false; } foreach ($b as $key => $bValue) { // check that expected value exists in the array if (!in_array($bValue, $a, true)) { return false; } // check that expected value occurs the same amount of times in both arrays if (count(array_keys($a, $bValue, true)) !== count(array_keys($b, $bValue, true))) { return false; } } return true; } it('consist of the same values', consistsOfTheSameValues([1], [1]) === true ); it('consist of the same values', consistsOfTheSameValues([1, 1], [1, 1]) === true ); it('consist of the same values', consistsOfTheSameValues(['1', 1], ['1', 1]) === true ); it('consist of the same values', consistsOfTheSameValues(['1', 1], [1, '1']) === true ); it('consist of the same values', consistsOfTheSameValues([1, '1'], ['1', 1]) === true ); it('consist of the same values', consistsOfTheSameValues([1, '1'], [1, '1']) === true ); it('consist of the same values', consistsOfTheSameValues(['x' => 1], ['x' => 1]) === true ); it('consist of the same values', consistsOfTheSameValues(['x' => 1], ['y' => 1]) === true ); it('consist of the same values', consistsOfTheSameValues(['y' => 1], ['x' => 1]) === true ); it('consist of the same values', consistsOfTheSameValues(['x' => 1, 'y' => 1], ['x' => 1, 'y' => 1]) === true ); it('consist of the same values', consistsOfTheSameValues(['y' => 1, 'x' => 1], ['x' => 1, 'y' => 1]) === true ); it('consist of the same values', consistsOfTheSameValues(['x' => 1, 'y' => 1], ['y' => 1, 'x' => 1]) === true ); it('consist of the same values', consistsOfTheSameValues(['y' => 1, 'x' => 1], ['y' => 1, 'x' => 1]) === true ); it('consist of the same values', consistsOfTheSameValues(['x' => 2, 'y' => 1], ['x' => 1, 'y' => 2]) === true ); it('does not consist of the same values', consistsOfTheSameValues([1], [2]) === false ); it('does not consist of the same values', consistsOfTheSameValues(['1'], [1]) === false ); it('does not consist of the same values', consistsOfTheSameValues([1], ['1']) === false ); it('does not consist of the same values', consistsOfTheSameValues([1], [1, 1]) === false ); it('does not consist of the same values', consistsOfTheSameValues([1, 1], [1]) === false ); it('does not consist of the same values', consistsOfTheSameValues(['1', 1], [1, 1]) === false ); it('does not consist of the same values', consistsOfTheSameValues([1, '1'], [1, 1]) === false ); it('does not consist of the same values', consistsOfTheSameValues([1, 1], ['1', 1]) === false ); it('does not consist of the same values', consistsOfTheSameValues([1, 1], [1, '1']) === false ); it('does not consist of the same values', consistsOfTheSameValues(['1', '1'], [1, 1]) === false ); it('does not consist of the same values', consistsOfTheSameValues(['1', '1'], ['1', 1]) === false ); it('does not consist of the same values', consistsOfTheSameValues(['1', '1'], [1, '1']) === false ); it('does not consist of the same values', consistsOfTheSameValues([1, 1], ['1', '1']) === false ); it('does not consist of the same values', consistsOfTheSameValues(['1', 1], ['1', '1']) === false ); it('does not consist of the same values', consistsOfTheSameValues([1, '1'], ['1', '1']) === false ); it('does not consist of the same values', consistsOfTheSameValues(['x' => 1], ['x' => 2]) === false ); it('does not consist of the same values', consistsOfTheSameValues(['x' => 1, 'y' => 1], ['x' => 1, 'y' => 2]) === false ); it('does not consist of the same values', consistsOfTheSameValues(['x' => 1, 'y' => 1], ['x' => 2, 'y' => 1]) === false ); it('does not consist of the same values', consistsOfTheSameValues(['x' => 2, 'y' => 1], ['x' => 1, 'y' => 1]) === false );
@Обновить:
Обширная модульная проверка ответа @ircmaxell: https://3v4l.org/5ivgm
Обширный модульный тест @Jon anwser: https://3v4l.org/CrTgQ
Принятый ответ не учитывает дубликаты. Вот мой прием
public function sameElements($a, $b) { sort($a); sort($b); return $a == $b; }