Laravel 5.7:基于多个密钥检测集合中的重复项(已完成),但如何将重复项移动到另一个集合



我有一个庞大的数据集合(数组项(。如果给定键的所有值都相同,则中的每个项都应区分为dupe将其想象成一个独特的组合键

$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就可以完成这项工作,因为文档非常清晰。

diff方法将集合与另一个集合或基于其值的普通PHP数组。此方法将返回原始集合中不存在的值集合:

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

然而,这并不奏效。我试过diffAssocdiffKeys。请帮帮我,我如何才能在一个全新的系列中拥有第四个(被欺骗的(项目和所有下一个被欺骗的项目?

编辑:

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

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

在集合上使用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将是一个集合,作为cleaned和all之间的差异。我已经操作了集合中的所有变量,如果需要,可以将它们转换为数组。

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

最新更新