#php #laravel #eloquent #collections
Вопрос:
У меня есть модель, в которой есть запрос, который возвращает следующую красноречивую коллекцию.
IlluminateDatabaseEloquentCollection {#4431
all: [
AppModelsProductVariation {#4429
attribute_value_id: 48,
name: "Storlek",
value: "Small",
},
AppModelsProductVariation {#4438
attribute_value_id: 41,
name: "Storlek",
value: "Medium",
},
AppModelsProductVariation {#4439
attribute_value_id: 34,
name: "Storlek",
value: "Large",
},
AppModelsProductVariation {#4440
attribute_value_id: 70,
name: "Color",
value: "Green",
},
],
}
Мне нужно отобразить эту коллекцию в массив с ключом «имя».
[
"Storlek" => [...]
"Color" => [...]
]
Я пытаюсь использовать keyBy, groupBy и mapWithKeys, с помощью этих методов он сохраняет только последний элемент в массиве
Решение, которое я нахожу, заключается в следующем:
$map = [];
foreach($variations as $value)
{
$key = $value["name"];
if(!isset($map[$key]))
$map[$key] = [];
$map[$key][] = $value;
}
return $map;
Это единственное решение? есть ли какое-либо другое лучшее решение?
Редактировать:
Я использую метод ->toArray() для повторения коллекции
Комментарии:
1. Просто используйте метод коллекции groupBy.
Ответ №1:
Вы ищете groupBy
(https://laravel.com/docs/8.x/collections#method-groupby) метод.
$mapped = $variations->groupBy(function($item){
return $item->name;
});
dd($mapped->toArray());
Это вернет ваши данные, сгруппированные по имени.
Кроме того, если вы хотите вернуть только значение (а не всю вариацию продукта), вы также можете переназначить сгруппированную коллекцию:
$mapped = $variations->groupBy(function($item){
return $item->name;
})->map(function($group){
return $group->map(function($item){
return $item->value;
});
});
dd($mapped->toArray());
Комментарии:
1. Я обновил свой ответ, так как думаю, что вы хотите, чтобы в качестве ключа была указана вся вариация продуктов, а не только их ценность. Как вы можете видеть, это незначительное изменение.
2. Это не работает. Это возвращает только один элемент в массиве, только последний
3. Извините, я действительно совершил ошибку. Я обновил ответ, теперь он исправлен.