PHP比较数组并返回不同之处

4

我有两个包含数据的数组,需要比较这两个数组并返回不匹配的数组。

我的两个数组长得都像这样:

$arr1 = array(
           array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
           array('name' => 'James', 'age' => '24', 'country' => 'spain' ),
           );

$arr2 = array(
           array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
           array('name' => 'James', 'age' => '54', 'country' => 'spffain' ),
        );

我希望能够按照姓名、年龄和国家进行数组比较,并返回不匹配的数组。
我的代码如下:
$intersect = array_uintersect($arr1, $arr2, 'compareDeepValue');
echo "<pre>", print_r($intersect);

function compareDeepValue($val1, $val2)
{
    return strcmp($val1['age'], $val2['age']);
    return strcmp($val1['country'], $val2['country']);
    return strcmp($val1['name'], $val2['name']);

}

上面的代码返回匹配的数组。我该如何更改代码以获取未匹配的数组?
期望输出:
Array
(
    [0] => Array
        (
            [name] => James
            [age] => 21
            [country] => spain
        )

)

1
你可以使用!strcmp($val1['age'], $val2['age']); - Santosh Jagtap
请查看此帖子:http://stackoverflow.com/questions/12169821/compare-differences-in-multidimensional-array - Javi
1
你的 compareDeepValue 函数有 3 个返回语句,但只有第一个是可达的。 - Wojciech Jasiński
5个回答

3
Your Arrays:

$arr1 = array(
           array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
           array('name' => 'James', 'age' => '24', 'country' => 'spain' ),
           );

$arr2 = array(
           array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
           array('name' => 'James', 'age' => '54', 'country' => 'spffain' ),
        );



foreach($arr1 as $key=>$arr)
{
 $bool = true; 
 $ar1 = $arr;
 $ar2 = $arr2[$key];

 foreach($ar1 as $ky=>$val)
{
  if($val != $ar2[$ky])
  {
    $bool = false;
    break;
  }
}

 if(!$bool)
{
  echo "Unmatched Arrays: \r\n";
  print_r($ar1); echo " in  Main Array 1 &  \r\n";
  print_r($ar2); echo " in  Main Array 2. \r\n";
}

}

亲爱的,布尔条件不正确。现在请尝试!谢谢! - Domain
@maxcheng 这个代码可能可以处理提供的示例数据,但是在我的看法中比较弱,而且不太可重用。如果你愿意的话,可以看看我的答案。 - Kleskowy

3

虽然回答中提到的代码可以实现,但是需要手动操作 :) 你可以使用现有的函数来代替手动操作。要计算数组之间的差异,应该使用array_udiff函数(或相关函数)。

你应该编写比较数组的函数,并使用它来计算差异,就像这样:

<?php
$arr1 = array(
       array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
       array('name' => 'James', 'age' => '24', 'country' => 'spain' ),
       );

$arr2 = array(
       array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
       array('name' => 'James', 'age' => '54', 'country' => 'spffain' ),
    );

// this function checks if 2 arrays with keys and scalar values are the same
function array_same_check($deepArr1, $deepArr2) {
   //check if arrays are the same
   $diffArr = array_diff_assoc($deepArr1, $deepArr2);
   //if $diffArr has 0 elements - arrays are the same
   if (count($diffArr) === 0) {
      return 0;
   }
   // arrays are not the same - return arbitratry 1 or -1
   return 1;
}

// now let's compare $arr1 and $arr2 you have 
// (meaning: compare the difference between arrays containing arrays) - we use function above
$differing = array_udiff ($arr1, $arr2, 'array_same_check');

print_r($differing);

我将这段代码复制到了PHPFiddle上,它的表现如预期一样。


@Kleskowy,我真的很喜欢这个,但是顺便提一下,这只会打印出主数组1中不匹配的数组,而不是主数组2中对应的不匹配的数组。 - Domain
@WisdmLabs 当然可以,就像所有的array_diff函数一样。如果再以相反的顺序传递数组,你就可以得到所有不匹配的结果。 - Kleskowy

2

试试这个

$arr1 = array(
       array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
       array('name' => 'James', 'age' => '24', 'country' => 'spain' ),
       );

$arr2 = array(
       array('name' => 'Alan', 'age' => '34', 'country' => 'usa'),
       array('name' => 'James', 'age' => '54', 'country' => 'spffain' ),
    );


$tmpArray = array();

 foreach($arr1 as $data1) {

  $duplicate = false;
   foreach($arr2 as $data2) {
    if($data1['name'] === $data2['name'] && $data1['age'] === $data2['age'] && $data1['country'] === $data2['country']) $duplicate = true;
    }

 if($duplicate === false) $tmpArray[] = $data1;
 }
 echo "<pre>", print_r($tmpArray);

2
$intersect = array_uintersect($arr1, $arr2, 'compareDeepValue');
print_r($intersect);
// add this and it will return the missing array.
print_r(array_diff_key($arr1, $intersect));

function compareDeepValue($val1, $val2)
{
    return strcmp($val1['age'], $val2['age']);
    return strcmp($val1['country'], $val2['country']);
    return strcmp($val1['name'], $val2['name']);
}

0

我想给你另一个可能的解决方案。我已经检查了代码,它似乎符合你的需求。

    /** @var array $arr1 */
    $arr1 = array(
            array(
                    'name'    => 'Alan',
                    'age'     => '34',
                    'country' => 'usa'
            ),
            array(
                    'name'    => 'James',
                    'age'     => '24',
                    'country' => 'spain'
            ),
    );

    /** @var array $arr2 */
    $arr2 = array(
            array(
                    'name'    => 'Alan',
                    'age'     => '34',
                    'country' => 'usa'
            ),
            array(
                    'name'    => 'James',
                    'age'     => '54',
                    'country' => 'spffain'
            ),
    );

    /** @var array $notMatched */
    $notMatched = array();
    /**
     * @var int   $index
     * @var array $element
     */
    foreach($arr1 as $index => $element) {
        /**
         * @var string $key
         * @var string $value
         */
        foreach($element as $key => $value) {
            if($arr2[$index][$key] !== $value) {
                $notMatched["arr1"] = $arr1[$index];
                $notMatched["arr2"] = $arr2[$index];
            }
        }
    }
    if(!empty($notMatched)) {
        echo "Unmatched arrays: \r\n";
        echo "Array 1:\r\n";
        print_r($notMatched["arr1"]);
        echo "Array 2:\r\n";
        print_r($notMatched["arr2"]);
    }

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