Добавить значения нескольких объектов коллекции для равных ключей

#php #laravel #eloquent

#php #laravel #красноречивый

Вопрос:

У меня есть несколько объектов в экземпляре коллекции, имеющих одинаковые ключи, но разные значения. Мне нужен способ добавить значения ключа поля количества в те же объекты.

 [
    0 => {
       "product_id": 1
       "quantity": "50"
       "price": "25.00"
    },
    1 => {
       "product_id": 3
       "quantity": "50"
       "price": "75.00"
    },
    2 => {
       "product_id": 2
       "quantity": "50"
       "price": "50.00"
    },
    3 => {
       "product_id": 3
       "quantity": "50"
       "price": "75.00"
    }    
]
  

Результирующий экземпляр должен иметь количества, добавленные в те же ключи элемента, как показано ниже.

 [
    0 => {
       "product_id": 1
       "quantity": "50"
       "price": "25.00"
    },
    1 => {
       "product_id": 2
       "quantity": "50"
       "price": "50.00"
    }
    2 => {
       "product_id": 3
       "quantity": "100"
       "price": "75.00"
    }
]
  

Я попытался выполнить итерацию по всем объектам и добавить / отредактировать объект следующим образом. Я не уверен, является ли это лучшим способом практики в коллекции Laravel.

 $newItems = [];

$items->each(function ($item, $key) use ($newItems) {
    $existId = array_column($newItems, 'id');
    if($existId){
        // add quantity to the existing item
    } else {
        // push item to items array
    }
});
  

Комментарии:

1. Просто небольшое примечание: похоже, что в вашем последнем блоке кода вы используете $items для того, что должно быть 2 разными переменными, и из-за этого вы получите ошибку, которая each не существует в массиве.

2. @RobinDeSchepper извините, это была опечатка

3. Это снова появляется в use ($items) и array_column($items 😉

4. @camille ваша проблема решена?

Ответ №1:

Вы можете использовать метод collection reduce для создания новой коллекции, в которую вы либо добавляете элементы, которых еще нет в новой коллекции, либо суммируете их количество:

 $total = $items->reduce(
  // The function that will insert or add the items together.
  function ($carry, $item) {
    if ($carry->has($item->product_id)) {
      $carry[$item->product_id]->quantity  = $item->quantity;
    } else {
      $carry[$item->product_id] = $item;
    }
    return $carry;
  }, 
  // The initial empty collection that will be filled up every iteration.
  collect([])
);