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


Merge two arrays containing objects and remove duplicate values

我需要将两个对象数组合并为 1 个数组并删除重复的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'],
]
您可以将

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
)

我一直在运行一些我能想象到的这样做方式的基准测试。我对堆叠大量 10-20 个字符串元素的数组进行了测试,结果是一个包含所有唯一字符串的数组。对于仅堆叠 2 个数组,这大致相同。

发现最快的是我尝试过的最简单的事情。

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

我将其称为"太幼稚而无法工作",因为它必须在每次迭代时对唯一数组进行排序。但是,这比任何其他方法都快。在 manyArray 中使用 500.000 个元素进行测试,每个元素包含 10-20 个字符串,而不是 PHP 7.3。

紧随其后的是这种方法,它慢了大约 10%。

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

在某些情况下,第二种方法可能会更好,因为它支持 in_array() 的"strict"参数进行严格的类型检查。如果设置为 true,则第二个选项确实比第一个选项慢得多(约 40%)。第一个选项不支持严格的类型检查。

更快的解决方案:

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

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

由于对象数组中的 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_unique在比较时应该调用 __toString(<</p>

div class="answers>
<?php
   $array1 = array("yellow", "red", "green", "orange", "purple");
   $array2 = array("pink", "brown", "green", "orange", "red");
   $array = array_unique(array_merge($array1, $array2));
   print_r($array);
?>
 
Array
(
    [0] => yellow
    [1] => red
    [2] => green
    [3] => orange
    [4] => purple
    [5] => pink
    [6] => brown
)

回答有点晚了,但我刚刚发现数组联合运算符+做得非常好(在第 3 部分找到)。

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