比较 laravel 中的两个集合数组

我正在使用laravel,我有两个看起来像这样的集合数组:


$collection1 = [

    ['id' => 1, 'name'=> 'phone', 'quantity' => 1, 'price' => 1200],

    ['id' => 2, 'name'=> 'tv', 'quantity' => 3, 'price' => 800],

];


$collection2 = [

    ['id' => 1, 'name'=> 'phone', 'quantity' => 1, 'price' => 1200],

    ['id' => 2, 'name'=> 'tv', 'quantity' => 3, 'price' => 400],

];

所以我需要知道它们是否相同,比较两个集合。如果在某些数组中,其中一个键(或多个键)具有不同的值,则它们将不再是相同的集合,例如在 1 个集合中,第二个项目的价格为 800,另一个集合400。有任何 laravel 集合的本机方法可以做到这一点?,或者我如何使用简单的 php 数组来做到这一点?


HUWWW
浏览 314回答 5
5回答

料青山看我应如是

Laravel 集合有一个名为 diff 的方法,使用此方法您可以获取集合中给定项目中不存在的项目。这些项目是 $collection2 ,它可以是一个数组或一个集合,所以你可以像这样在这两个集合之间获取不同的项目$collection1->diff($collection2);它返回一个 Illuminate\Support\Enumerable 类。您可以通过调用 all() 来获取这些项目:$collection = collect([1, 2, 3, 4, 5]);$differentItems = $collection->diff([2, 4, 6, 8]);$differentItems->all();// [1, 3, 5]此代码属于 laravel 文档。https://laravel.com/docs/7.x/collections#method-diff。最后,您可以将 $differentItems 转换为布尔值。像这样:$collection = collect([1, 2, 3, 4, 5]);$differentItems = $collection->diff([2, 4, 6, 8]);$differentItems->isEmpty();// return false$collection = collect([1, 2, 3, 4, 5]);$differentItems = $collection->diff($collection);$differentItems->isEmpty();// return true更多链接https://laravel.com/api/7.x/Illuminate/Support/Collection.html#method_diff https://laravel.com/api/7.x/Illuminate/Support/Enumerable.html

子衿沉夜

遵循比较功能:function compareCollections($c1, $c2) {    // If the colletions have different sizes we return false:    if (count($c1) != count($c2)) {        return false;    }    // The collections have the same size, we check element by element:    foreach($c1 as $item) {        // We find the current element in $c1 in $c2:        $itemToCompare = array_filter($c2, function ($compareItem) use ($item) {            return ($compareItem['id'] == $item['id']);        });        // If we did not find the element in $c2, the collections are different:        if (empty($itemToCompare)) {            return false;        }        $itemToCompare = current($itemToCompare);        // We now use PHP to check the element keys:        $diff = array_diff_key($item, $itemToCompare);        // If there is a different, return false:        if (!empty($diff)) {            return false;        }           }    // If everything is ok until here, the collections are the same:    return true;}和一个测试:$collection1 = [    ['id' => 1, 'name'=> 'phone', 'quantity' => 1, 'price' => 1200],    ['id' => 2, 'name'=> 'tv', 'quantity' => 3, 'price' => 800],];$collection2 = [    ['id' => 1, 'name'=> 'phone', 'quantity' => 1, 'price' => 1200],    ['id' => 2, 'name'=> 'tv', 'quantity' => 3, 'price' => 400],];$collection3 = [    ['id' => 1, 'name'=> 'tv', 'quantity' => 1, 'price' => 1200],    ['id' => 2, 'name'=> 'tv', 'quantity' => 3],];var_dump(compareCollections($collection1, $collection2)); // truevar_dump(compareCollections($collection1, $collection3)); // false

慕仙森

所以先对每个元素进行序列化,然后再进行比较。    $serialize1 = $collection1->map(function ($item) {        return serialize($item);    });    $serialize2 = $collection2->map(function ($item) {        return serialize($item);    });dd($serialize1->diff($serialize2)->isEmpty());

收到一只叮咚

据我所知,由于您的集合项是数组,因此没有本地简单的 Laravel 方法可以这样做,您应该编写一个函数来比较它们:因此,假设您有:$collection1 = collectt([    ['id' => 1, 'name'=> 'phone', 'quantity' => 1, 'price' => 1200],    ['id' => 2, 'name'=> 'tv', 'quantity' => 3, 'price' => 800],]);$collection2 = collect([    ['id' => 1, 'name'=> 'phone', 'quantity' => 1, 'price' => 1200],    ['id' => 2, 'name'=> 'tv', 'quantity' => 3, 'price' => 400],]);例如,您可以通过以下方式比较它们:    private function collectionsAreEqual($collection1, $collection2)    {        if ($collection1->count() != $collection2->count()) {            return false;        }        //assuming that, from each id, you don't have more that one item:        $collection2 = $collection2->keyBy('id');        foreach ($collection1->keyBy('id') as $id => $item) {            if (!isset($collection2[$id])) {                return false;            }            //your items in the collection are key value arrays             // and can compare them with == operator            if ($collection2[$id] != $item) {                return false;            }        }        return true;    }    dd(collectionsAreEqual($collection1, $collection2));

万千封印

此方法仅在两个集合具有相同的键顺序时才有效。默认情况下,Laravel 有一个 diffAssoc 方法,它实际上比较集合中的单个项目。如果要比较两个集合数组,则必须创建自己的解决方案。这是我创建(或者你可以说扩展)收集方法的解决方案。首先,我映射每个项目并序列化该项目,然后对另一个集合执行相同的操作。使用 diffAssoc 方法获取差异并对最终输出进行反序列化。AppServiceProvider.php<?phpnamespace App\Providers;use Illuminate\Support\Collection;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider{&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Register any application services.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @return void&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; public function register()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Bootstrap any application services.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @return void&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; public function boot()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Collection::macro('diffAssocMultiple', function ($anotherCollection) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* @var $this Collection */&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return $this->map(function($arr) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return serialize($arr);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })->diffAssoc($anotherCollection->map(function($arr) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return serialize($arr);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }))->map(function($arr) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return unserialize($arr);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; }}用法$diff = $collectionOne->diffAssocMultiple($collectionTwo);请注意,此新方法返回另一个集合(基于非零)。并且它没有 diffAssoc 所具有的“all()”方法。如果你想要一个从零开始的索引数组,那么使用 values 函数。$diff = $collectionOne->diffAssocMultiple($collectionTwo)->values();
打开App,查看更多内容
随时随地看视频慕课网APP