合并两个包含对象的数组并删除重复的值

我需要将两个对象数组合并为一个数组,并删除重复的 email值。

我该怎么做?

下面是我的示例数组:

$array1 = [
(object) ["email" => "gffggfg"],
(object) ["email" => "wefwef@test.it"],
(object) ["email" => "wefewf"],
];
$array2 = [
(object) ["email" => "gffggfg@test.it"],
(object) ["email" => "wefwef"],
(object) ["email" => "wefewf"],
];

我预期的结果是:

[
(object) ['email' => 'gffggfg'],
(object) ['email' => 'wefwef@test.it'],
(object) ['email' => 'wefewf'],
(object) ['email' => 'gffggfg@test.it'],
(object) ['email' => 'wefwef'],
]
123052 次浏览

您可以将 array_merge()函数与 array_unique()函数结合起来(这两个标题都是不言而喻的)

$array = array_unique (array_merge ($array1, $array2));

如果我没理解错的话:

 $a1 = Array(1,2,3,4);
$a2 = Array(4,5,6,7);
$array =  array_diff(array_merge($a1,$a2),array_intersect($a1,$a2));
print_r($array);

返回

Array
(
[0] => 1
[1] => 2
[2] => 3
[5] => 5
[6] => 6
[7] => 7
)

更快的解决方案:

function concatArrays($arrays){
$buf = [];
foreach($arrays as $arr){
foreach($arr as $v){
$buf[$v] = true;
}
}
return array_keys($buf);
}




$array = concatArrays([$array1, $array2]);

有点晚了,但是我刚刚发现数组联合操作符 +完成了相当大的工作(在第3部分中找到了 给你)。

$array1 + $array2 = $array //if duplicate found, the value in $array1 will be considered ($array2 value for array_merge, if keys clearly specified)

我已经运行了一些基准测试的所有方式,我可以想象做到这一点。我在堆叠10-20个字符串元素的大量数组上运行了测试,得到了一个包含所有唯一字符串的数组。对于仅仅堆叠2个数组来说,这应该是相同的。

我找到的最快的东西是我试过的最简单的东西。

$uniques = [];
foreach($manyArrays as $arr ) {
$uniques = array_unique(array_merge($uniques, $arr));
}

我给这个命名为“太天真无法工作”,因为它必须在每次迭代中对惟一数组进行排序。但是这比其他任何方法都要快。使用许多 Ararray 中的500.000个元素进行测试,每个元素包含 PHP 7.3中的10-20个字符串。

紧随其后的是这种方法,它的速度要慢10% 左右。

$uniques = [];
foreach($manyArrays as $arr ) {
foreach($arr as $v) {
if( !in_array($v, $uniques, false) ) {
$uniques[] = $v;
}
}
}

在某些情况下,第二种方法可能会更好,因为它支持 In _ array()的“ strong”参数以进行严格的类型检查。如果设置为 true,则第二个选项的速度明显慢于第一个选项(约40%)。第一个选项不支持严格的类型检查。

因为对象数组中的 email属性包含非数值,所以可以临时分配第一级键(使用 array_column()) ,然后将两个数组与联合运算符合并(无函数操作)。

如果临时键干扰了下一个进程,可以使用 array_values()重新索引数组。

密码: (演示)

var_export(
array_values(
array_column($array1, null, 'email')
+ array_column($array2, null, 'email')
)
);

产出:

array (
0 =>
(object) array(
'email' => 'gffggfg',
),
1 =>
(object) array(
'email' => 'wefwef@test.it',
),
2 =>
(object) array(
'email' => 'wefewf',
),
3 =>
(object) array(
'email' => 'gffggfg@test.it',
),
4 =>
(object) array(
'email' => 'wefwef',
),
)

“合并并保持独特的对象”也将使用一个特殊的标志。

密码: (演示)

var_export(
array_unique(
array_merge($array1, $array2),
SORT_REGULAR
)
);
// same result as other snippet

很古老的线,但是..。 OP 的数组包含对象。 如果我是 op,我将声明一个类,它使用返回电子邮件的 _ _ toString ()函数在构造函数中接收子数组。 如果 op 然后将他的对象变成该类的实例,那么当比较时 array _ only 应该调用 _ _ toString ()