递归数组映射与 Laravel 集合 map() 助手


Recursive Array Map with Laravel Collection map() Helper

我有一个数据的集合。

$array = [
    [
        'id' => 1,
        'name' => 'some1',
        'type' => 'type1',
        'color' => 'color1',
        'quantity' => 1
    ],
    [
        'id' => 2,
        'name' => 'some1',
        'type' => 'type1',
        'color' => 'color1',
        'quantity' => 1
    ],
    [
        'id' => 3,
        'name' => 'some1',
        'type' => 'type1',
        'color' => 'color2',
        'quantity' => 1
    ],
    [
        'id' => 4,
        'name' => 'some2',
        'type' => 'color1',
        'color' => 'type1',
        'quantity' => 1
    ],
     ......
];

具有不同的名称、类型和颜色

我想按名称、类型和颜色对数据进行分组,结果是带有相同组数据的摘要的数组数据。

首先,我使用这种方式:

function groupedData($array)
{
    $collection = [];
    collect($array)->groupBy('name')->map(
        function ($item) use (&$collection) { 
            return $item->groupBy('type')->map(
                function ($item) use (&$collection) { 
                    return $item->groupBy('color')->map(
                        function ($item) use (&$collection) {
                            $quantity = $item->sum('quantity');
                            $collection[] = collect($item[0])->merge(compact('quantity'));
                        }
                    );
                }
            ); 
        }
    );
    return $collection;
}

我希望输出应该是这样的:

$grouped = [
    [
        'id' => 1,
        'name' => 'some1',
        'type' => 'type1',
        'color' => 'color1',
        'quantity' => 2
    ],
    [
        'id' => 2,
        'name' => 'some1',
        'type' => 'type1',
        'color' => 'color2',
        'quantity' => 1
    ],
    [
        'id' => 3,
        'name' => 'some2',
        'type' => 'type1',
        'color' => 'color1',
        'quantity' => 2
    ],
    [
        'id' => 4,
        'name' => 'some2',
        'type' => 'type2',
        'color' => 'color1',
        'quantity' => 2
    ],
];

其中,数量表示组项目的数量。

但是,我的问题是当所需更改时。以防万一:当用户想要添加其他类别进行分组时,例如:用户可能希望按名称,类型,颜色和大小进行分组。

:如何做一个函数,让它更加简单灵活,所以在需要改变的时候不需要改变代码吗?

谢谢你的回答。

你要找的东西是排序,而不是分组。

这里有一个简单的方法:

function sort($array, $keys) {
    return collect($array)->sortBy(function ($item) use ($keys) {
        return array_reduce($keys, function ($carry, $key) use ($item) {
            return $carry + $item[$key];
        }, '');
    })->all();
}

这里有一个简短的解释:

  1. 我们使用的是集合的 sortBy 方法,该方法让我们使用一个回调函数,该函数将返回一个字符串来确定排序顺序。
  2. 我们使用键上的array_reduce来构建要排序的键中所有值的单个字符串。
  3. Laravel 的集合对象将使用该生成的字符串对集合进行排序。
  4. 最后,我们调用 all 方法从集合中获取基础数组。如果要实际返回集合,可以删除最后一个all调用。