【问题标题】:PHP - Check if two arrays are equalPHP - 检查两个数组是否相等
【发布时间】:2011-04-15 15:25:02
【问题描述】:

我想检查两个数组是否相等。我的意思是:相同的大小、相同的索引、相同的值。我该怎么做?

按照用户的建议使用!==,如果数组中至少有一个元素不同,我希望以下内容会打印enter,但实际上并非如此。

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

    echo "enter";
}

【问题讨论】:

  • 你用的=太多了,应该是!==或者!=
  • 只是为了记录(因为我的编辑改回“用户”)它是“用户”:english.stackexchange.com/questions/105116/…
  • ['a'] == [0]true。好吧,这只是 PHP。
  • @DávidHorváth 真的很奇怪,总是使用它的好习惯 ===
  • @DávidHorváth,松散的比较不仅在 PHP 中是松散的。如果您查看 JS,您会感到惊讶。只是在你更好地理解事情之前不要使用。

标签: php arrays


【解决方案1】:
$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.

Array Operators

编辑

不等式运算符为!= 而非恒等式运算符为!== 以匹配等式 运算符== 和身份运算符===

【讨论】:

  • 附注:这种方法适用也适用于多维数组(以前对我来说不是那么明显)。
  • PS:解决方案是使用array_values($a)==array_values($b)... 另一个常见的问题是关于唯一值,所以请记住存在array_unique()
  • 说 == 检查匹配的键/值对有点误导。它似乎实际上检查了值 == 彼此。所以你可能会惊讶地发现 array(0) == array('not zero') 是真的。
  • @nawfal:你的假设是错误的。 ['a', 'b'] 是一个数组[0 => 'a', 1 => 'b'],而['b', 'a'] 是一个数组[0 => 'b', 1 => 'a']。这就是为什么它们没有我的答案中所述的相同键/值对,这就是为什么 == 在它们之间不起作用。
  • @StefanGehrig 哦,你是对的。我会留下我的评论,以表明我的愚蠢:)
【解决方案2】:

根据this page.

注意:接受的答案适用于关联数组,但它不会像预期的那样适用于索引数组(解释如下)。如果您想比较其中任何一个,请使用此解决方案。此外,此函数可能不适用于多维数组(由于 array_diff 函数的性质)。

使用$a == $b$a === $b测试两个索引数组,其中元素的顺序不同,失败,例如:

<?php
    (array("x","y") == array("y","x")) === false;
?>

那是因为上面的意思是:

array(0 =&gt; "x", 1 =&gt; "y")array(0 =&gt; "y", 1 =&gt; "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 建议),因为它可以提高速度。

【讨论】:

  • 注意:multidimensional arrays 无法正常工作
  • 以上评论为假。如果 $b 包含 $a 的所有元素加上一些额外的元素,则两个数组不相等,但上面的代码会说它们是。
  • 可能也值得添加 count($a) == count($b)
  • @super_ton:是的,在调用array_diff 之前可以加快比较速度。我会添加它。谢谢
  • 很遗憾,它在某些情况下不起作用,例如我用下面的案例$a = [1, 2, 2]; $b = [2, 1, 1];进行了测试,它返回了true,但是这两个数组显然不一样。
【解决方案3】:

尝试序列化。这也会检查嵌套的子数组。

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

【讨论】:

  • 如果键和值像使用比较一样移动,则会出现问题。但是,假设它们应该 100% 相同,这是检查深度相等性的最简单、最简单的方法!
  • 我想这是最好的解决方案!如果之前已排序,它可以比较多维和关联数组!
  • 如果数组被认为是一个 SET,这不起作用:它应该在所有嵌套级别上进行排序,以便能够检查相同的项目是否包含在任何顺序中。
【解决方案4】:

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

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'],结果将是错误的。
【解决方案5】:

将它们与其他值进行比较:

if($array_a == $array_b) {
  //they are the same
}

您可以在此处阅读有关所有数组运算符的信息: http://php.net/manual/en/language.operators.array.php 请注意,例如=== 还会检查数组中元素的类型和顺序是否相同。

【讨论】:

  • ===,具体取决于所需的行为。
【解决方案6】:
function compareIsEqualArray(array $array1,array $array2):bool
{

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

}

【讨论】:

  • 解释代码示例的作用很有帮助。这也适用于多维数组吗?
  • array_diff 如果 array_diff 返回空数组两个数组相等,则从数组中获取不同的元素
  • array_diff 返回一个数组,其中包含 array1 中不存在于任何其他数组中的条目
【解决方案7】:

!=== 将不起作用,因为这是语法错误。正确的方式是!==(不是三个“等于”符号)

【讨论】:

    【解决方案8】:
    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 转换就不会占用太多内存。

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

    【讨论】:

      【解决方案9】:

      另一种检查相等而不考虑值顺序的方法是使用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;
      }
      

      【讨论】:

        【解决方案10】:

        一种方式:(为https://www.rfc-editor.org/rfc/rfc6902#section-4.6 实现“认为相等”)

        这种方式允许其成员排序不同的关联数组 - 例如除了 php 之外,它们在所有语言中都被认为是平等的 :)

        // recursive ksort
        function rksort($a) {
          if (!is_array($a)) {
            return $a;
          }
          foreach (array_keys($a) as $key) {
            $a[$key] = ksort($a[$key]);
          }
          // SORT_STRING seems required, as otherwise
          // numeric indices (e.g. "0") aren't sorted.
          ksort($a, SORT_STRING);
          return $a;
        }
        
        
        // Per https://www.rfc-editor.org/rfc/rfc6902#section-4.6
        function considered_equal($a1, $a2) {
          return json_encode(rksort($a1)) === json_encode(rksort($a2));
        }
        

        【讨论】:

        • 相信你应该是:$a[$key] = rksort($a[$key]);
        【解决方案11】:

        array_diff — 计算数组的差异

        http://php.net/manual/en/function.array-diff.php

        array array_diff ( array $array1 , array $array2 [, array $... ] )
        

        array1 与一个或多个其他数组进行比较,并返回array1 中不存在于任何其他数组中的值。

        【讨论】:

        • OP 想要“检查两个数组是否相等”。 array_diff 不能告诉你。试试array_diff([1, 2], [1, 2, 'hello'])
        【解决方案12】:

        数组的语法问题

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

        【讨论】:

          【解决方案13】:

          这里是如何与数组进行比较并获得它们之间不同之处的示例。

          $array1 = ['1' => 'XXX', 'second' => [
                      'a' => ['test' => '2'],
                      'b' => 'test'
                  ], 'b' => ['no test']];
          
                  $array2 = [
                      '1' => 'XX',
                      'second' => [
                          'a' => ['test' => '5', 'z' => 5],
                          'b' => 'test'
                      ],
                      'test'
                  ];
          
          
                  function compareArrayValues($arrayOne, $arrayTwo, &$diff = [], $reversed = false)
                  {
                      foreach ($arrayOne as $key => $val) {
                          if (!isset($arrayTwo[$key])) {
                              $diff[$key] = 'MISSING IN ' . ($reversed ? 'FIRST' : 'SECOND');
                          } else if (is_array($val) && (json_encode($arrayOne[$key]) !== json_encode($arrayTwo[$key]))) {
                              compareArrayValues($arrayOne[$key], $arrayTwo[$key], $diff[$key], $reversed);
                          } else if ($arrayOne[$key] !== $arrayTwo[$key]) {
                              $diff[$key] = 'DIFFERENT';
                          }
                      }
                  }
          
                  $diff = [];
                  $diffSecond = [];
          
                  compareArrayValues($array1, $array2, $diff);
                  compareArrayValues($array2, $array1, $diffSecond, true);
          
                  print_r($diff);
                  print_r($diffSecond);
          
                  print_r(array_merge($diff, $diffSecond));
          

          结果:

          Array
          (
              [0] => DIFFERENT
              [second] => Array
                  (
                      [a] => Array
                          (
                              [test] => DIFFERENT
                              [z] => MISSING IN FIRST
                          )
          
                  )
          
              [b] => MISSING IN SECOND
              [1] => DIFFERENT
              [2] => MISSING IN FIRST
          )
          

          【讨论】:

            【解决方案14】:

            如果你想检查非关联数组,这里是解决方案:

            $a = ['blog', 'company'];
            $b = ['company', 'blog'];
            
            (count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';
            // Equals
            

            【讨论】:

            • 我得到了“等于”:$a = array('a', 'b', 'c', 'd');$b = array('a', 'c', 'b');echo (count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';
            【解决方案15】:

            以下解决方案适用于您可以作为回调传递的自定义相等函数。请注意,它不检查数组顺序。

            trait AssertTrait
            {
                /**
                 * Determine if two arrays have the same elements, possibly in different orders. Elements comparison function must be passed as argument.
                 *
                 * @param array<mixed> $expected
                 * @param array<mixed> $actual
                 *
                 * @throws InvalidArgumentException
                 */
                public static function assertArraysContainSameElements(array $expected, array $actual, callable $comparisonFunction): void
                {
                    Assert::assertEquals(\count($expected), \count($actual));
            
                    self::assertEveryElementOfArrayIsInAnotherArrayTheSameAmountOfTimes($expected, $actual, $comparisonFunction);
                    self::assertEveryElementOfArrayIsInAnotherArrayTheSameAmountOfTimes($actual, $expected, $comparisonFunction);
                }
            
                /**
                 * @param array<mixed> $needles
                 * @param array<mixed> $haystack
                 *
                 * @throws InvalidArgumentException
                 */
                private static function assertEveryElementOfArrayIsInAnotherArrayTheSameAmountOfTimes(
                    array $needles,
                    array $haystack,
                    callable $comparisonFunction
                ): void {
                    Assert::assertLessThanOrEqual(\count($needles), \count($haystack));
            
                    foreach ($needles as $expectedElement) {
                        $matchesOfExpectedElementInExpected = \array_filter(
                            $needles,
                            static fn($element): bool => $comparisonFunction($expectedElement, $element),
                        );
            
                        $matchesOfExpectedElementInActual = \array_filter(
                            $haystack,
                            static fn($element): bool => $comparisonFunction($expectedElement, $element),
                        );
            
                        Assert::assertEquals(\count($matchesOfExpectedElementInExpected), \count($matchesOfExpectedElementInActual));
                    }
                }
            }
            

            当我想确保返回预期的元素但我不关心排序时,我通常在数据库集成测试中使用它。

            【讨论】:

              【解决方案16】:

              比较两个数组是否相等的正确方法是使用严格相等 (===),它以递归方式进行比较。现有答案无法对任意数组(任意深度和顺序的数组,包含顺序数组和关联数组的混合)进行递归排序,因此无法处理任意数组的比较。顺序数组是具有顺序键 (0,1,2,3...) 的关联数组,而关联数组没有顺序键。

              要对这些任意数组进行排序,我们必须:

              1. 向下遍历到没有更多子数组的叶节点
              2. 通过序列化然后排序来对顺序数组进行排序(无需使用自定义比较器)
              3. 按键对关联数组进行排序

              以下代码实现了上述解决方案。欢迎对代码进行改进。

              function recur_sort( &$array ) {
                  foreach ( $array as &$value ) {
                     if ( is_array( $value ) ) recur_sort( $value );
                  }
              
                  if ( is_sequential_array( $array ) ) {
                      $array = array_map( function( $el ) { return json_encode( $el ); }, $array  );
                      sort( $array, SORT_STRING );
                      $array = array_map( function( $el ) { return json_decode( $el, true ); }, $array  );
                      return;
                  } else {
                      return ksort( $array );
                  }
              }
              
              function is_sequential_array(Array &$a) {
                  $n = count($a);
                  for($i=0; $i<$n; $i++) {
                      if(!array_key_exists($i, $a)) {
                          return false;
                      }
                  }
                  return true;
              }
              

              示例(在 PHPUnit 中):

              //A stricter and recursive assertEqualsCanonicalizing
              public function assertSameCanonicalizing( $expected, $actual ) {
                  recur_sort( $expected );
                  recur_sort( $actual );
                  $this->assertSame( $expected, $actual );
              }
              

              【讨论】:

                【解决方案17】:

                如果您想检查您的数组是否具有严格相等的 (===) 键和值关联,您可以使用以下函数:

                function array_eq($a, $b) {
                    // If the objects are not arrays or differ in their size, they cannot be equal
                    if (!is_array($a) || !is_array($b) || count($a) !== count($b)) {
                        return false;
                    }
                    // If the arrays of keys are not strictly equal (after sorting),
                    // the original arrays are not strictly equal either
                    $a_keys = array_keys($a);
                    $b_keys = array_keys($b);
                    array_multisort($a_keys);
                    array_multisort($b_keys);
                    if ($a_keys !== $b_keys) {
                        return false;
                    }
                    // Comparing values
                    foreach ($a_keys as $key) {
                        $a_value = $a[$key];
                        $b_value = $b[$key];
                        // Either the objects are strictly equal or they are arrays
                        // which are equal according to our definition. Otherwise they
                        // are different.
                        if ($a_value !== $b_value && !array_eq($a_value, $b_value)) {
                            return false;
                        }
                    }
                    return true;
                }
                

                【讨论】:

                  【解决方案18】:

                  使用php函数array_diff(array1, array2);

                  它将返回数组之间的差异。如果它是空的,那么它们是相等的。

                  示例:

                  $array1 = array(
                      'a' => 'value1',
                  
                      'b' => 'value2',
                  
                      'c' => 'value3'
                   );
                  
                  $array2 = array(
                      'a' => 'value1',
                  
                      'b' => 'value2',
                  
                      'c' => 'value4'
                   );
                  
                  $diff = array_diff(array1, array2);
                  
                  var_dump($diff); 
                  
                  //it will print array = (0 => ['c'] => 'value4' ) 
                  

                  示例 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); 
                  
                  //it will print empty; 
                  

                  【讨论】:

                  • 从技术上讲,它不会返回数组之间的差异。该文档指出“将 array1 与一个或多个其他数组进行比较,并返回 array1 中不存在于任何其他数组中的值。”。因此,如果 array1 中的所有值都存在于 array2 中,即使 array2 有更多值,array_diff 也会返回一个空数组
                  • 不“打印空”,打印一个空数组(在修复了大约十几个语法错误之后)。也许你可以使用(count(array_diff($a1, $a2)) + count(array_diff($a2, $a1))) === 0 来测试数组是否“相等”
                  • 我修正了语法( not null 是空的,我在混合逗号 -.- )。你的提议我认为太多了。检查它是否是一个空数组就足够了。
                  猜你喜欢
                  • 2020-02-12
                  • 1970-01-01
                  • 2020-05-05
                  • 2015-08-21
                  • 1970-01-01
                  • 2020-09-16
                  • 1970-01-01
                  相关资源
                  最近更新 更多