我有两个数组$ a和$ b,需要检查它们是否包含完全相同的元素(与顺序无关)。我正在考虑使用
if (sizeof($a)==sizeof($b) AND array_diff($a,$b)==array())
{
}
但是我不熟悉PHP,所以我想知道:还有更好的方法吗?
由于我需要将它们用作集合,所以也许我不应该使用数组,而要使用其他东西。
接受的答案是错误。它will将失败: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
);
@@ update:
@ ircmaxell答案的广泛单元测试:https://3v4l.org/5ivgm
@ Jon anwser的广泛单元测试:https://3v4l.org/CrTgQ
嗯,我们可以做这样的事情:
if (count(array_diff(array_merge($a, $b), array_intersect($a, $b))) === 0) {
//they are the same!
}
它起作用的原因是,array_merge
将创建一个大数组,同时包含array_merge
和$a
的所有元素($b
,$a
或两者中的所有元素) 。 $b
将创建一个仅包含array_intersect
和array_intersect
中所有元素的数组。因此,如果它们不同,则必须至少有一个元素未同时出现在两个数组中...
还请注意,$a
不是实际的函数/构造,它是别名。我建议使用$b
来简化说明...
接受的答案无法说明重复项。这是我的看法
sizeof
如果您将数组视为集合:
然后您的方法几乎是正确的(您需要删除元素计数的相等性测试)。
如果数组包含同一元素的多个副本很重要:
那么您的方法是not正确的。您需要使用sizeof
对数组进行排序,然后将其与count()
进行比较。这应该更快,因为它可以在看到一个差异时中止比较而无需遍历整个数组。
更新:
[明确说明了OP的方法何时正确或不正确,并在此加入了public function sameElements($a, $b)
{
sort($a);
sort($b);
return $a == $b;
}
可能比sort
更好的建议。
为了您的娱乐,我将添加一个示例来说明您的条件不正确:
sort
===
我建议使用其他模型。也许将元素添加为数组的键,但这只有在它们是整数或字符串的情况下才有可能。
sort
这将强制唯一性。使用此模型,您可以在asort
上使用您的条件。