在php中比较数组,而不考虑顺序

在php中比较数组,而不考虑顺序,php,arrays,comparison,set,Php,Arrays,Comparison,Set,这里有两个数组,$a和$b,需要检查它们是否包含完全相同的元素(与顺序无关)。我正在考虑使用 if (sizeof($a)==sizeof($b) AND array_diff($a,$b)==array()) { } 但我对PHP还不熟悉,所以我想知道:有没有更好的方法 因为我需要将它们作为集合使用,也许我根本不应该使用数组,而应该使用其他东西。如果您认为数组是集合的话: 那么您的方法几乎是正确的(您需要放弃元素计数的相等性测试) 如果数组包含同一元素的多个副本很重要: 那么你的方法是不正

这里有两个数组,$a和$b,需要检查它们是否包含完全相同的元素(与顺序无关)。我正在考虑使用

if (sizeof($a)==sizeof($b) AND array_diff($a,$b)==array())
{

}
但我对PHP还不熟悉,所以我想知道:有没有更好的方法


因为我需要将它们作为集合使用,也许我根本不应该使用数组,而应该使用其他东西。

如果您认为数组是集合的话:

那么您的方法几乎是正确的(您需要放弃元素计数的相等性测试)

如果数组包含同一元素的多个副本很重要

那么你的方法是不正确的。您需要对数组进行排序,然后将它们与
==
进行比较。这应该更快,因为它可以在看到一个差异时中止比较,而不会遍历整个阵列

更新:


明确了OP的方法何时正确,同时也包含了
sort
可能比
asort
更好的建议。

我们可以这样做:

if (count(array_diff(array_merge($a, $b), array_intersect($a, $b))) === 0) {
    //they are the same!
}
它工作的原因是,它将生成一个大数组,其中包含
$a
$b
的所有元素(位于
$a
$b
或两者中的所有元素)。将创建一个数组,该数组仅包含
$a
$b
中的所有元素。因此,如果它们不同,则必须至少有一个元素不出现在两个数组中


还要注意的是,它不是一个实际的函数/构造,而是一个别名。为了清楚起见,我建议使用
count()

只是为了消遣,我将添加一个示例,说明您的条件不正确:

<?php
$a = array(1, 1, 2);
$b = array(1, 2, 3);

var_dump(sizeof($a)==sizeof($b) AND array_diff($a,$b)==array());
?>
这将强制执行唯一性。使用此型号,您可以在
数组\u键($arr)

上使用您的条件,接受的答案是错误的。它将在以下情况下失败:

$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;
}
加上相当广泛的单元测试:


接受的答案无法解释重复的答案。这是我的照片

public function sameElements($a, $b)
{
   sort($a);
   sort($b);
   return $a == $b;
}

从被问到现在已经过去了十年,但我偶然发现了类似的挑战,我想分享我自己的解决方案,该解决方案也适用于多维阵列:

公共静态函数isname($a,$b,bool$is\u strict=true):bool
{
//首先检查PHP评估
如果($a==b):($a==b))
{
返回true;
}
//比较标量是在上面完成的,现在是递归数组比较
如果(!is_数组($a)| |!is_数组($b))
{
返回false;
}
foreach([$a,$b],$b,$a]]作为[$x,$y])
{
foreach($x为$xkey=>$xval)
{
如果(!array_key_存在($xkey,$y))
{
返回false;
}
如果(!self::isname($xval,$y[$xkey],$is_strict))
{
返回false;
}
}
}
返回true;
}

实际上,我的建议也是sizeof而不是size\u+1。这相当于调用strtolower进行不区分大小写的比较。他希望将它们作为集合使用<在这种情况下,需要的函数是code>sort
,而不是
asort
。事实上,我想念Python的set:-)。@ring0:Alin确实有道理,但这实际上取决于你想要的是数学意义上的set还是数组。我认为答案现在正确地涵盖了这两种情况。@如果需要严格的类型检查,带有排序的Jon解决方案将不起作用,这两个数组将不会被视为相同:
['1',1',1']
或这两个:
[1',1',1]
。测试:谢谢,非常优雅。作为一名数学家,我喜欢它。我只是不确定这是否会比Jon的建议更快,我毫不怀疑它的效率更低,但它更健壮,因为它会检测到@Alin在他的回答中指出的情况……它将在
$a=['x'=>1,'y'=>2]上失败$b=['x'=>1,'y'=>1]。为什么计数(array_diff($array1,$array2))=0不起作用?谢谢!!谢谢你给我看代码板。看来我将来会需要它。猜猜为什么我的解决方案不正确?答案是否定的,因为这是一个好的发现,但这真的应该是一个注释(或者至少是一个答案应该指定一个可能的修复)…@Pietro,因为您假设数组不能多次包含同一个元素,但是,正如我在示例中所做的,它们可以。如果要强制唯一性,可能需要将元素添加为具有某些默认值的键,例如
true
。但只有在钥匙打开的情况下才有可能。谢谢!(实际上,在我的程序中,我的假设是正确的,但正如你所注意到的,我将这些数组看作集合,这是一种危险的做法)@ircmaxel因为Pietro确信他的解决方案是有效的:“有更好的方法吗?”,我认为有必要单独发表一篇文章。至于另一个选择,我很快会加上一个选择严格的可能性,跳过可选的数组内检查的可能性,以及更多的测试。非常优雅,在需要弱比较的情况下可以工作:警告的话,严格比较将导致
相同的元素(['1',1',[1',1'])==false
<?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
);
public function sameElements($a, $b)
{
   sort($a);
   sort($b);
   return $a == $b;
}