Laravel 5.7:基于多个键检测集合中的重复项(完成)但如何将重复项移动到另一个集合?
Posted
技术标签:
【中文标题】Laravel 5.7:基于多个键检测集合中的重复项(完成)但如何将重复项移动到另一个集合?【英文标题】:Laravel 5.7: Detecting duplicates in a collection based on multiple keys (done) but how to move dupes to another collection? 【发布时间】:2019-05-01 01:57:49 【问题描述】:我有大量数据(数组项)。如果给定键的所有值都相同,则其中的每个项目都应区分为重复项。 把它想象成一个独特的复合键。
$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);
);
【问题讨论】:
【参考方案1】:当您在集合上使用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 之间的区别。我已经对集合中的所有变量进行了操作,您可以根据需要将它们转换为数组。
如果有任何问题,我想你会理解上面的代码。
【讨论】:
哇,你的差异和我的完全一样,这意味着问题是我没有将集合$recordsAll
和$recordsCleaned
中的每个项目都包装为集合。现在好了。谢谢!
@Matt 很高兴看到它对您有用。如果它确实帮助您解决问题,那么请通过接受此答案来关闭问题。
会做,会做! ?
@Matt Cheers ;)以上是关于Laravel 5.7:基于多个键检测集合中的重复项(完成)但如何将重复项移动到另一个集合?的主要内容,如果未能解决你的问题,请参考以下文章
markdown 在Laravel 5.7种子文件中截断具有外键约束的表。