我有大量的数据(数组项)。如果给定键的所有值都相同,则其中的每个项目都应区分为重复。 将其想象为唯一的组合键。
$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)
];
在上面的示例中,唯一的组合键是unique
和unique2
的组合。
我可以删除骗子。我是这样的:
$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();
但是,这不起作用。我也尝试过diffAssoc
和diffKeys
。请帮助我,我如何才能将第4个(重复的)物品和所有下一个重复的东西放在一个全新的收藏中?
编辑:
我想出了以下解决方案,但是从性能的角度来看,这并不好,因为生产馆藏将有近百万件商品。
$recordsDupes = collect([]);
$recordsAll->each(function ($item) use ($recordsCleaned, $recordsDupes) {
if ($recordsCleaned->contains($item) === false) {
$recordsDupes->push($item);
}
});
答案 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
中,将作为已清除变量与全部变量之间的区别的集合。我已经操作了集合中的所有变量,并且可以根据需要将它们转换为数组。
如果有任何问题,我想您会理解上面的代码。