Laravel — Сопоставьте красноречивую коллекцию, используя значение в качестве ключа, вставляя массив в ключи

#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. Извините, я действительно совершил ошибку. Я обновил ответ, теперь он исправлен.