【问题标题】:Merge Two Laravel Collections and Sum the Values合并两个 Laravel 集合并对值求和
【发布时间】:2018-07-31 00:01:18
【问题描述】:

我有 10 个(以下示例中使用了 3 个)集合,我需要按键合并,但需要对这些值求和。我的收藏是这样的:

[
    'key1' => ['value1' => 5, 'value2' => 3, 'value3' => 0],
    'key2' => ['value1' => 1, 'value2' => 6, 'value3' => 2],
    'key3' => ['value1' => 0, 'value2' => 0, 'value3' => 1],
]

[
    'key1' => ['value1' => 3, 'value2' => 1, 'value3' => 7],
    'key2' => ['value1' => 1, 'value2' => 3, 'value3' => 2],
    'key3' => ['value1' => 1, 'value2' => 6, 'value3' => 1],
]

[
    'key1' => ['value1' => 2, 'value2' => 3, 'value3' => 9],
    'key2' => ['value1' => 3, 'value2' => 8, 'value3' => 3],
    'key3' => ['value1' => 1, 'value2' => 0, 'value3' => 6],
]

我想获得一个结果如下所示的集合:

[
    'key1' => ['value1' => 10, 'value2' => 7, 'value3' => 16],
    'key2' => ['value1' => 5, 'value2' => 17, 'value3' => 7],
    'key3' => ['value1' => 2, 'value2' => 6, 'value3' => 8],
]

我是否缺少内置的 Laravel Collection 方法,或者实现此目的的最佳方法是什么?

编辑:(更多信息)这些值始终是数字。任何集合中都没有字符串值。

edit2:有些人问我试过什么。我已经试过了:

$merged = [];
foreach ($seeds as $seed) {
    foreach ($seed as $location => $values) {
        foreach ($values as $key => $value) {
            $merged[$location][$key] = $value + ($merged[$location][$key] ?? 0);
        }
    }
}

我只是想知道是否有更简洁的方法来实现相同的目标,而不是使用 3 个 foreach 循环。

【问题讨论】:

  • 你真的尝试过什么吗?你走了多远,你尝试了什么?
  • 您能向我们展示您为实现这一目标所做的努力吗?
  • @Option 查看我的编辑
  • @rahulsm 查看我的编辑

标签: php arrays laravel collections


【解决方案1】:

我用 laravel 7 做了这个,以防它适用于某人

$test = collect([
   [
     'key1' => ['value1' => 5, 'value2' => 3, 'value3' => 0],
     'key2' => ['value1' => 1, 'value2' => 6, 'value3' => 2],
     'key3' => ['value1' => 0, 'value2' => 0, 'value3' => 1],
   ],

   [
     'key1' => ['value1' => 3, 'value2' => 1, 'value3' => 7],
     'key2' => ['value1' => 1, 'value2' => 3, 'value3' => 2],
     'key3' => ['value1' => 1, 'value2' => 6, 'value3' => 1],
   ],

   [
     'key1' => ['value1' => 2, 'value2' => 3, 'value3' => 9],
     'key2' => ['value1' => 3, 'value2' => 8, 'value3' => 3],
     'key3' => ['value1' => 1, 'value2' => 0, 'value3' => 6],
   ]
]);
$col = $test->reduce(function ($carry, $item) {
    return $carry->mergeRecursive($item);
}, collect([]));
$col->transform(function($item) {
    return collect($item)->map(function ($item2) {
        return collect($item2)->sum();
    });
});

【讨论】:

    【解决方案2】:

    真的认为会有比循环更容易做的事情,但似乎该解决方案仍然比我想出的解决方案更好。 Flatten 即使改变深度也会移除键,mapToGroups 仅在返回包含单个键/值对的关联数组时有效,pluck 带来一些其他困难等等。

    这是我想出来的

    $test = collect([
       [
         'key1' => ['value1' => 5, 'value2' => 3, 'value3' => 0],
         'key2' => ['value1' => 1, 'value2' => 6, 'value3' => 2],
         'key3' => ['value1' => 0, 'value2' => 0, 'value3' => 1],
       ],
    
       [
         'key1' => ['value1' => 3, 'value2' => 1, 'value3' => 7],
         'key2' => ['value1' => 1, 'value2' => 3, 'value3' => 2],
         'key3' => ['value1' => 1, 'value2' => 6, 'value3' => 1],
       ],
    
       [
         'key1' => ['value1' => 2, 'value2' => 3, 'value3' => 9],
         'key2' => ['value1' => 3, 'value2' => 8, 'value3' => 3],
         'key3' => ['value1' => 1, 'value2' => 0, 'value3' => 6],
       ]
    ]);
    $mappedCollection = collect($test->first())->keys()->mapWithKeys(function($item,$key) use($test){
       return[
          $item => $test->map(function ($mapItem, $mapKey) use($item) {         
             return $mapItem[$item];
          })
       ];
    })->mapWithKeys(function($item,$key){
       $eachLine = collect($item->first())->keys()->mapWithKeys(function($mapItem) use($item){
          return[ $mapItem => $item->sum($mapItem)  ];
       });       
       return [$key =>  $eachLine];
    })->all();
    
    dd($mappedCollection);
    

    集合文档来源https://laravel.com/docs/5.6/collections

    【讨论】:

    • 似乎是一种残酷的方法,但我接受了答案,因为您确实设法使用 Laravel 的集合来做到这一点。我最终只使用了 3 个 foreach 循环。
    • 完全同意比执行 foreach 循环更容易。使用 laravel 集合可能有更好(不太明显)和更简单的方法来做到这一点,但我把它留给 laravel 的 Jon Skeet ^^
    • 为什么不直接使用 map 和 reduce 呢?
    猜你喜欢
    • 2016-06-05
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 1970-01-01
    • 2019-12-01
    相关资源
    最近更新 更多