Карта рекурсивных массивов с коллекцией 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();
}
Вот краткое объяснение:
- Мы используем коллекцию
sortBy
метод, который позволяет нам использовать функцию обратного вызова, которая будет возвращать строку для определения порядка сортировки. - Мы используем
array_reduce
на ключах, чтобы построить единственную строку из всех значений в ключах, по которым мы хотим отсортировать. - Объект коллекции Laravel будет использовать эту результирующую строку для упорядочения коллекции.
- Наконец, мы называем
all
метод, чтобы получить базовый массив из коллекции. Если вы действительно хотите вернуть коллекцию, вы можете удалить последнийall
вызов.