使用Laravel Collection map()Helper的递归数组映射

时间:2016-04-20 14:17:59

标签: php laravel collections

我有一组数据。

$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
    ],
];

其中数量表示组项目数。

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

问题:如何制作一个可以使其更加简单灵活的功能,因此在需要更改时无需更改代码?

感谢您的回答。

1 个答案:

答案 0 :(得分:0)

您正在寻找的是排序,而不是分组。

这是一种简单的方法:

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电话。