Laravel 5.7:基于多个键(完成)检测集合中的重复项,但是如何将重复对象移至另一个集合?

时间:2018-11-29 04:03:26

标签: php arrays laravel laravel-5 collections

我有大量的数据(数组项)。如果给定键的所有值都相同,则其中的每个项目都应区分为重复。 将其想象为唯一的组合键

$recordsAll = [
    ['unique1' => 'foo', 'unique2' => 'bar', 'whatever1' => 'whatever1'], // 1st OK
    ['unique1' => 'baz', 'unique2' => 'zaz', 'whatever2' => 'whatever2'], // 2nd OK
    ['unique1' => 'foo', 'unique2' => 'kkk', 'whatever3' => 'whatever3'], // 3rd OK (because unique2 is kkk not bar)
    ['unique1' => 'bar', 'unique2' => 'zaz', 'whatever4' => 'whatever4'], // 4th DUPE (dupe of the 2nd because on both unique1 is bar and unique2 is zaz)
];

在上面的示例中,唯一的组合键是uniqueunique2的组合。

我可以删除骗子。我是这样的:

$recordsAll = collect($recordsAll);
$recordsCleaned = $recordsAll->unique(function ($item) {
    return $item['unique1'].$item['unique2'];
});

我可以通过对两个结果进行计数来确认它是否有效。收集所有东西显然应该给我4,而清理后的东西应该给我3,它们确实可以给我……

dd($recordsAll->count(), $recordsCleaned->count()); // prints 4 and 3

我不知道该怎么做(或者至少我有一个主意,但它不起作用)是将重复的记录存储在另一个数组(集合)中。因此,我不想只删除重复项并使用清理后的集合。稍后,我还想对包含重复项的集合执行一些逻辑。

我认为一个简单的diff将为我完成工作,since the documentation is quite clear

  

diff方法将集合与另一个集合进行比较,或者   基于其值的纯PHP数组。此方法将返回   给定中不存在的原始集合中的值   集合:

$dupes = $recordsAll->diff($recordsCleaned);
$dupes->all();

但是,这不起作用。我也尝试过diffAssocdiffKeys。请帮助我,我如何才能将第4个(重复的)物品和所有下一个重复的东西放在一个全新的收藏中?

编辑:

我想出了以下解决方案,但是从性能的角度来看,这并不好,因为生产馆藏将有近百万件商品。

$recordsDupes = collect([]);
$recordsAll->each(function ($item) use ($recordsCleaned, $recordsDupes) {
    if ($recordsCleaned->contains($item) === false) {
        $recordsDupes->push($item);
    }
});

1 个答案:

答案 0 :(得分:2)

在集合上使用diff方法时,在多维情况下,必须在集合内部具有集合。因此,您的代码应如下所示:

$recordsAll = [
            ['unique1' => 'foo', 'unique2' => 'bar', 'whatever1' => 'whatever1'], // 1st OK
            ['unique1' => 'baz', 'unique2' => 'zaz', 'whatever2' => 'whatever2'], // 2nd OK
            ['unique1' => 'foo', 'unique2' => 'kkk', 'whatever3' => 'whatever3'], // 3rd OK (because unique2 is kkk not bar)
            ['unique1' => 'baz', 'unique2' => 'zaz', 'whatever4' => 'whatever4'], // 4th DUPE (dupe of the 2nd because on both unique1 is bar and unique2 is zaz)
        ];
$recordsAll = collect($recordsAll);

$recordsCleaned = $recordsAll->unique(function ($item) {
    return $item['unique1'].$item['unique2'];
});


$recordsAll = collect($recordsAll->toArray())->map(function($row) {
                                            return collect($row);
                                    });
$recordsCleaned = collect($recordsCleaned->toArray())->map(function($row) {
                                        return collect($row);
                                    });

$diff = $recordsAll->diff($recordsCleaned);

在上面的代码变量$diff中,将作为已清除变量与全部变量之间的区别的集合。我已经操作了集合中的所有变量,并且可以根据需要将它们转换为数组。

如果有任何问题,我想您会理解上面的代码。