1

如何获得包含数据类型的数组的差异?

第一个数组:

Array
(
  [0] => Array
  (
    [ID] => 21323154
    [NAME] => Name_2
    [PREVIEW_TEXT] => Text_2
  )
)

第二个数组:

Array
(
  [0] => Array
  (
    [ID] => 543547564
    [NAME] => Name_1
    [PREVIEW_TEXT] => Text_1
  )
  [1] => Array
  (
    [ID] => 222213322
    [NAME] => Name_2
    [PREVIEW_TEXT] => Text_2
  )
  [2] => Array
  (
    [ID] => 333876833
    [NAME] => Name_3
    [PREVIEW_TEXT] => Text_3
  )
)

结果应该是一个数组:

Array
(
  [0] => Array
  (
    [ID] => 543547564
    [NAME] => Name_1
    [PREVIEW_TEXT] => Text_1
  )
  [1] => Array
  (
    [ID] => 333876833
    [NAME] => Name_3
    [PREVIEW_TEXT] => Text_3
  )
)

我尝试了不同的选项,但他们都返回了发现差异的结果,即第一个数组。

我有不同的身份证

4

3 回答 3

4

只需尝试:

$output = array_udiff($arraySecond, $arrayFirst, function($a, $b){
    return strcmp($a['NAME'], $b['NAME']);;
});

输出:

array(2) {
  [0] =>
  array(3) {
    'ID' =>
    int(543547564)
    'NAME' =>
    string(6) "Name_1"
    'PREVIEW_TEXT' =>
    string(6) "Text_1"
  }
  [2] =>
  array(3) {
    'ID' =>
    int(333876833)
    'NAME' =>
    string(6) "Name_3"
    'PREVIEW_TEXT' =>
    string(6) "Text_3"
  }
}
于 2014-05-08T10:16:14.113 回答
2

如果两个数组都很大,array_diff效率会非常低,因为它将第一个数组的每个元素与第二个数组的每个元素进行比较。更快的解决方案是将过程分为两个步骤:首先,生成一组要删除的键:

 $remove = array();
 foreach($firstArray as $item)
      $remove[$item['name']] = 1;

然后遍历第二个数组并将“好”项添加到结果中:

 $result = array(); 
 foreach($secondArray as $item)
      if(!isset($remove[$item['name']]))
           $result []= $item;

这将为您提供线性性能,array_diff而是二次的。

于 2014-05-08T10:23:01.513 回答
1

将两个数组与您想要的字段(列)进行比较,然后只返回那些条目(感谢键):

$col  = 'NAME';
$diff = array_intersect_key($b, array_diff(array_column($b, $col), array_column($a, $col)));
print_r($diff);

如果您更喜欢这种不那么二次但线性的,您也可以通过迭代来解决它(受georg's answer的启发但array_column()再次使用):

$filtered = function ($col, $a, $b) {
    return iterator_to_array(call_user_func(function () use ($col, $a, $b) {
        $coled = array_flip(array_column($a, $col));
        foreach ($b as $bk => $bv) if (!isset($coled[$bv[$col]])) yield $bk => $bv;
    }));
};

print_r($filtered('NAME', $a, $b));

使用$a$b概述,您将获得两个示例的以下结果:

Array
(
    [0] => Array
        (
            [ID] => 543547564
            [NAME] => Name_1
            [PREVIEW_TEXT] => Text_1
        )

    [2] => Array
        (
            [ID] => 333876833
            [NAME] => Name_3
            [PREVIEW_TEXT] => Text_3
        )

)

// 1.) - diff against column, intersect keys
$filtered = function($col, $a, $b) {
    return array_intersect_key($b, array_diff(array_column($b, $col), array_column($a, $col)));
};

// 2.) - iterate and take only unset by column
$filtered = function ($col, $a, $b) {
    return iterator_to_array(call_user_func(function () use ($col, $a, $b) {
        $coled = array_flip(array_column($a, $col));
        foreach ($b as $bk => $bv) if (!isset($coled[$bv[$col]])) yield $bk => $bv;
    }));
};

// 3.) - array_udiff against column
$filtered = function($col, $a, $b) {
    return array_udiff($b, $a, function ($a, $b) use ($col) {
        return strcmp($a[$col], $b[$col]);
    });
};

用法:

print_r($filtered('NAME', $a, $b));

$a包含要从数组中删除的元素的数组在哪里$b$a问题的第一个数组和问题$b的第二个数组也是如此。

于 2014-05-08T10:26:26.720 回答