如何获得包含数据类型的数组的差异?
第一个数组:
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
)
)
我尝试了不同的选项,但它们都返回了发现差异的结果,即第一个数组。
我有一个不同的ID
试试:
$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"
}
}
如果两个数组都很大,array_diff
将非常低效,因为它将第一个数组的每个元素与第二个数组的每个元素进行比较。一个更快的解决方案是将这个过程分成两个步骤:首先,生成一组要删除的键:
$remove = array();
foreach($firstArray as $item)
$remove[$item['name']] = 1;
,然后遍历第二个数组,并将"good"项添加到结果中:
$result = array();
foreach($secondArray as $item)
if(!isset($remove[$item['name']]))
$result []= $item;
这将为您提供线性性能,而array_diff
是二次的。
根据您想要的字段(列)对两个数组进行Diff,然后只返回那些条目(多亏了键):
$col = 'NAME';
$diff = array_intersect_key($b, array_diff(array_column($b, $col), array_column($a, $col)));
print_r($diff);
如果你喜欢这个不那么二次但线性的,你也可以通过迭代来解决它(灵感来自georg的答案,但再次使用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
是问题的第二个数组。