PHP - 检查两个数组是否相等

374

我想检查两个数组是否相等,即:大小相同,索引相同,值相同。我该如何做到这一点?

根据用户的建议使用 !== ,我期望如果数组中至少有一个元素不同,则以下代码将输出enter,但实际上并没有。

if (($_POST['atlOriginal'] !== $oldAtlPosition) 
    or ($_POST['atl'] !== $aext) 
    or ($_POST['sidesOriginal'] !== $oldSidePosition) 
    or ($_POST['sidesOriginal'] !== $sideext)) {

    echo "enter";
}

19
你过度使用了 = 符号,应该使用 !==!= - jeroen
36
只是为了记录(因为我的编辑被改回了“an user”),应该是“a user”:http://english.stackexchange.com/questions/105116/is-it-a-user-or-an-user - teynon
12
['a'] == [0]true。这只是 PHP 的语法。 - Dávid Horváth
3
@DávidHorváth 这真的很奇怪,一个好的实践是始终使用 ===。 - AFA Med
6
@DávidHorváth,松散比较不仅在PHP中存在。如果你看一下JS,你会感到惊讶的。在理解更深入之前,请不要使用它。 - ryabenko-pro
20个回答

697
$arraysAreEqual = ($a == $b); // TRUE if $a and $b have the same key/value pairs.
$arraysAreEqual = ($a === $b); // TRUE if $a and $b have the same key/value pairs in the same order and of the same types.

请参见数组运算符

编辑

不等于运算符是!=,非恒等运算符是!==,这两者可匹配相等运算符==和恒等运算符===


105
一则旁注: 这种方法同样适用于多维数组(以前对我来说并不那么明显)。 - trejder
8
解决方法是使用 array_values($a)==array_values($b)。另一个常见问题是有关唯一值的,因此请记住存在 array_unique() - Peter Krauss
2
说“==”检查匹配的键/值对有点误导。它似乎实际上是检查值是否相等。因此,您可能会惊讶地发现array(0) == array('not zero')为true。 - Andrew
59
@nawfal:你的假设是错误的。['a', 'b']是一个数组,键值对为[0 => 'a', 1 => 'b'],而['b', 'a']是一个数组,键值对为[0 => 'b', 1 => 'a']。这就是为什么它们没有与我在回答中声明的相同的键/值对,也是为什么==在它们之间不起作用的原因。 - Stefan Gehrig
42
哦,你说得对。我将保留我的评论,以使我的愚蠢显而易见 :) - nawfal
显示剩余4条评论

119
根据此页面。请注意:接受的答案适用于关联数组,但在使用索引数组时(如下所述),其效果可能不如预期。如果要比较两种类型的数组,请使用此解决方案。此外,由于array_diff函数的特性,此函数可能无法处理多维数组。例如,使用$a == $b$a === $b来测试两个元素顺序不同的索引数组会失败。
<?php
    (array("x","y") == array("y","x")) === false;
?>

这是因为上面的意思是:

array(0 => "x", 1 => "y")array(0 => "y", 1 => "x") 不同。

要解决这个问题,使用以下代码:

<?php
function array_equal($a, $b) {
    return (
         is_array($a) 
         && is_array($b) 
         && count($a) == count($b) 
         && array_diff($a, $b) === array_diff($b, $a)
    );
}
?>

添加了比较数组大小的功能(由super_ton建议),这可能会提高速度。


4
注意:在处理多维数组时可能无法按预期工作。 - maersu
11
上述评论是错误的。如果数组$b$包含所有数组$a$的元素并且还多了一些额外的元素,那么这两个数组不相等,但上述代码会认为它们相等。 - Ghola
3
也许值得添加 count($a) == count($b)。 - stefan
3
@super_ton: 是的,在调用array_diff之前可以加速比较。我会添加它。谢谢。 - lepe
9
很遗憾,在某些情况下它无法正常工作,例如我已经测试了以下情况$a = [1, 2, 2]; $b = [2, 1, 1];,它返回了true,但是这两个数组显然不是相同的。 - AwesomeGuy
显示剩余2条评论

40

尝试使用serialize。这将检查嵌套的子数组。

$foo =serialize($array_foo);
$bar =serialize($array_bar);
if ($foo == $bar) echo "Foo and bar are equal";

10
如果键和值像使用比较一样被移动,那么会产生问题。但是,假设它们预期完全相同,这是检查深层相等性最清晰、最简单的方法! - Kevin Peno
2
我猜这是最好的解决方案!如果多维数组和关联数组已排序,它可以进行比较! - Rafael Moni
1
如果将数组视为SET,则此方法无效:必须对所有嵌套级别进行排序,以便检查是否以任何顺序包含相同的项。 - Pablo Pazos
如果值的顺序不同或键的顺序不同,则无法工作。 - devsmt

37

即使数组的键以不同顺序给出,也能使用简短的解决方案:

public static function arrays_are_equal($array1, $array2)
{
    array_multisort($array1);
    array_multisort($array2);
    return ( serialize($array1) === serialize($array2) );
}

不错的选择!但请注意,此方法使用严格类型比较,因此如果您想比较 [1,2,3] 和 ['1','2','3'],结果将为 false。 - ChronoExp
请注意,如果您关心索引值的数字索引数组将无法使用array_multisort(),因为它会重新索引数字键。 - Costa
1
这是一个比其他答案好的回答,但它没有涵盖嵌套数组键以不同顺序出现的情况。 - Vasiliy Artamonov
不错的答案,但无法处理这种情况:array_equal( ['aa' =>['bb' => 'b', 'aa' => 'a']], ['aa' =>['aa' => 'a', 'bb' => 'b']] ) - devsmt

18
function compareIsEqualArray(array $array1,array $array2):bool
{

   return (array_diff($array1,$array2)==[] && array_diff($array2,$array1)==[]);

}

2
解释代码示例正在做什么是有帮助的。这也适用于多维数组吗? - k0pernikus
2
array_diff从数组中获取不同的元素,如果array_diff返回空数组,则两个数组相等。 - dılo sürücü
array_diff函数返回一个数组,其中包含array1中不在任何其他数组中出现的条目。 - Anand Singh
这无法处理array_equal([1, 2, 2], [2, 1, 1])array_equal([1, 2, 3], ['1', '2', '3'])这两种情况。 - devsmt

15

将它们像其他值一样进行比较:

if($array_a == $array_b) {
  //they are the same
}
你可以在此处了解所有关于数组运算符的信息: http://php.net/manual/en/language.operators.array.php 例如,请注意 === 运算符也会检查数组中元素的类型和顺序是否相同。

7
根据所需的行为,可以使用“或者”(or)或者“等于等于”(===)。 - Matthew Flaschen

10
if (array_diff($a,$b) == array_diff($b,$a)) {
  // Equals
}

if (array_diff($a,$b) != array_diff($b,$a)) {
  // Not Equals
}

在我看来,使用array_diff比使用array_intersect更好,因为在这种检查中,返回的差异通常比相似性少,这样bool转换所需的内存就会更少。

编辑请注意,此解决方案适用于普通数组,并补充了上面发布的仅适用于字典的==和===解决方案。


很抱歉,这无法处理array_equal([0], [false])array_equal([1, 2, 2], [2, 1, 1])这两种情况。 - devsmt

5

另一种不考虑值顺序检查相等的方法是使用http://php.net/manual/en/function.array-intersect.php,如下所示:

$array1 = array(2,5,3);
$array2 = array(5,2,3);
if($array1 === array_intersect($array1, $array2) && $array2 === array_intersect($array2, $array1)) {
    echo 'Equal';
} else {
    echo 'Not equal';
}

这里有一个版本,它也可以使用http://php.net/manual/en/function.array-uintersect.php来处理多维数组:

$array1 = array(
    array(5, 2),
    array(3, 6),
    array(2, 9, 4)
);
$array2 = array(
    array(3, 6),
    array(2, 9, 4),
    array(5, 2)
);

if($array1 === array_uintersect($array1, $array2, 'compare') && $array2 === array_uintersect($array2, $array1, 'compare')) {
    echo 'Equal';
} else {
    echo 'Not equal';
}

function compare($v1, $v2) {
    if ($v1===$v2) {
        return 0;
    }
    if ($v1 > $v2) return 1;
    return -1;
}

很抱歉,这无法处理array_equal([1, 2, 2], [2, 1, 1])以及键顺序不同的多维关联数组。 - devsmt

2

给定:

$array1 = ['a', 'b', '3'];
$array2 = ['a', 'b', '3'];

$array1 == $array2  //true
$array1 === $array2 //true

给定:

$array1 = ['a', 'b', 3];
$array2 = ['a', 'b', '3'];

$array1 == $array2  //true
$array1 === $array2 //false

给定:

$array1 = ['3', 'a', 'b'];
$array2 = ['a', 'b', '3'];

$array1 == $array2  //false
$array1 === $array2 //false

解决方案,按相同顺序排序

$array1 = ['3', 'a', 'b'];
$array2 = ['a', 'b', '3'];

sort($array1);
sort($array2);

$array1 == $array2  //true
$array1 === $array2 //true

2

您的数组存在语法问题

$array1 = array(
    'a' => 'value1',
    'b' => 'value2',
    'c' => 'value3',
 );

$array2 = array(
    'a' => 'value1',
    'b' => 'value2',
    'c' => 'value3',
 );

$diff = array_diff($array1, $array2);

var_dump($diff); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接