Карта рекурсивных массивов с коллекцией Laravel map() Помощник

У меня есть коллекция данных.

$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 ответ

То, что вы ищете, это сортировка, а не группировка.

Вот простой способ сделать это:

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 вызов.
Другие вопросы по тегам