【问题标题】:PHP: Built-in function to check whether two Array values are equal ( Ignoring the order)PHP:检查两个数组值是否相等的内置函数(忽略顺序)
【发布时间】:2009-09-10 08:42:02
【问题描述】:

是否有 PHP 的内置函数让我检查两个数组是否包含相同的值(顺序不重要?)。

例如,我想要一个对以下两个输入返回 true 的函数:

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

编辑:我本可以对这两个数组进行排序并比较它们,但由于我是个懒惰的人,我还是更喜欢一个我可以拉出来使用的单线。

【问题讨论】:

  • 代码应该如何处理数组具有多个相同值的实例的情况,例如array(1, 2, 3) vs array(1, 2, 3, 1)?一些答案将返回真,而另一些则为假。此外,由于通过 count() 短路,有些会返回不一致的结果,并且在第一个示例中将返回 false,但如果将 array(1, 2, 3, 1)array(1, 2, 3, 2) 进行比较,则返回 true。我的猜测是这不适用于您的情况,但对于任何寻找可能存在重复条目的答案的人,必须注意使用满足您特定要求的算法。

标签: php arrays


【解决方案1】:

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();

【讨论】:

  • 您只能将empty 与变量一起使用。
  • gumbo:不,你可以在数组上使用它就好了。取自php.net/empty>:“以下事物被认为是空的:#array()(一个空数组)”
  • 秋葵是对的。您不能将函数的返回值与empty 一起使用。这才是他真正想说的。您必须将 array_diff 的返回值存储在临时变量中,或者只使用 not 运算符:return !array_diff($a1, $a2)
  • @knittl:不,您只能测试变量而不能测试值。 empty() 仅检查变量,因为其他任何内容都会导致解析错误。 再次,请参阅docs.php.net/empty
  • ionut:好的,这更有意义。我刚试过,你们都是对的。我编辑了我的答案以使用布尔转换(否定)
【解决方案2】:

最好的解决方案是对两个数组进行排序,然后比较它们:

$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) 的复杂性。所以你最好使用排序方法。

【讨论】:

  • 因为我是个懒惰的人,我还是更喜欢可以拉出来使用的单线。
  • @Ngu Soon Hui - 所以将 Gumbo 的代码包装成一个函数 (array_equals($arr1,$arr2))?
  • 如果投反对票的人评论了他为什么投了我的答案,那将会很有帮助。
  • @Gumbo 也许,因为他或她是个病态的混蛋(对不起!:~),这就是为什么他或她否决了一个完全有效且专业书面的答案? :]
【解决方案3】:

上面的array_diff() 方法不起作用。

php.net 的手册说array_diff() 这样做:

“返回一个数组,该数组包含 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

【讨论】:

  • +1 这是一种更好的方法。我今天发现了这个问题并最终使用了!array_diff($a,$b) && !array_diff($b,$a)。不是最好的解决方案,但它确实有效。
  • 附注:虽然,这不是 OP 的问题,但值得记住的是,使用 array_diff()(以及类似 array_intersect())将 在多维数组上失败 (PHP 注意:数组到字符串的转换),而使用简单的数组运算符===== 可以在这样的数组上正常工作。
【解决方案4】:

你可以使用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
}

但是,这种方法的一个问题是数组可以包含重复的元素,并且仍然匹配。

【讨论】:

  • 有谁知道php中diff和sort之间的性能差异细节?
  • if (array_diff($a, $b)) {} 可以。空数组评估为假。
  • 使用array_diff 很容易。但它需要额外的空间 (O(n)),因为在存储 A 的那些元素的地方创建了一个额外的数组,这些元素也不是 B.
  • @Gumbo:有理由关心吗?
  • @SilentGhost:如果你有无限的时间和空间,就不会。但谁有呢?
【解决方案5】:

您可以使用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%。

【讨论】:

  • 格式化注意事项:您使用了写得很糟糕的 HTML 而不是 Markdown(已修复),而且您似乎不喜欢每个部分开头的大写字母(已修复)。所以总的来说,我应该反对你的懒惰! :] 但是,另一方面,您提供了一个特殊而有趣的答案,所以没关系! :]
【解决方案6】:

您只需要使用array_diff()进行单向比较,并使用count()进行倒置关系。

if (count($a1) == count($a2) && !array_diff($a1, $a2)) {
    // equal arrays
}

【讨论】:

  • 拒绝投票作为一般解决方案,因为这仅在两个数组都是唯一的情况下才有效。如果任一数组包含多个相同值的实例,它将不会给出正确的结果。
【解决方案7】:

如果要比较的数组仅包含字符串和/或整数,array_count_values 允许您通过验证两个数组是否包含相同的值和每个值在两个数组中出现的次数相同。

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

【讨论】:

    【解决方案8】:

    作为来自@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}
    

    【讨论】:

      猜你喜欢
      • 2012-05-31
      • 1970-01-01
      • 2017-04-25
      • 1970-01-01
      • 1970-01-01
      • 2019-02-23
      • 2012-10-03
      • 2013-10-12
      • 2020-02-12
      相关资源
      最近更新 更多