【问题标题】:Merge objects of an array in PHP using Eloquent使用 Eloquent 在 PHP 中合并数组的对象
【发布时间】:2018-01-16 23:00:44
【问题描述】:

我使用 Laravel 的 Eloquent ORM 从我的数据库中抓取了一组对象(我没有使用 Laravel,只是将 Eloquent 集成到我自己的框架中)。我使用transform 方法遍历集合和unserialize 每条记录的列之一,然后collapsed 集合将所有未序列化的对象放在一个数组中。

逻辑如下:

  $orders = Order::where('user', $user)->orderBy('id', 'desc')->get();

  $orders->transform(function($order, $key) {

    $order->cart = unserialize($order->cart);

    $items = $order->cart->items;

    return $items;
  });

  $collapsed = $orders->collapse();

然后输出:

[
   {
      "qty": "2",
      "price": 200,
      "item": {
         "id": 1,
         "title": "Black Hoodie",
         "img": "https://s3.amazonaws.com/bucket/black-hoodie.jpg",
         "description": "Plain Black Hoodie.",
         "price": 100
      }
   },
   {
      "qty": "2",
      "price": 200,
      "item": {
         "id": 2,
         "title": "Green Hoodie",
         "img": "https://s3.amazonaws.com/bucket/green-hoodie.jpg",
         "description": "Plain Green Hoodie.",
         "price": 100
      }
   },
   {
      "qty": 1,
      "price": 100,
      "item": {
         "id": 2,
         "title": "Green Hoodie",
         "img": "https://s3.amazonaws.com/bucket/green-hoodie.jpg",
         "description": "Plain Green Hoodie.",
         "price": 100
      }
   },
   {
      "qty": 1,
      "price": 100,
      "item": {
         "id": 1,
         "title": "Black Hoodie",
         "img": "https://s3.amazonaws.com/bucket/black-hoodie.jpg",
         "description": "Plain Black Hoodie.",
         "price": 100
      }
   }
]

现在我接下来要完成的是将这个数组中所有相同的对象(理想情况下通过它们的"item":{"id"} 值)组合成一个对象——将它们的qtyprice 属性加在一起,留下item属性相同。

我想要的输出是

[
   {
      "qty": "3",
      "price": 300,
      "item": {
         "id": 1,
         "title": "Black Hoodie",
         "img": "https://s3.amazonaws.com/bucket/black-hoodie.jpg",
         "description": "Plain Black Hoodie.",
         "price": 100
      }
   },
   {
      "qty": "3",
      "price": 300,
      "item": {
         "id": 2,
         "title": "Green Hoodie",
         "img": "https://s3.amazonaws.com/bucket/green-hoodie.jpg",
         "description": "Plain Green Hoodie.",
         "price": 100
      }
   }
]

Eloquent 拥有 TONS 的许多可用于处理集合的好方法,我只是坚持使用正确的组合来有效地实现我想做的事情。

【问题讨论】:

    标签: php arrays laravel merge eloquent


    【解决方案1】:

    试试这个:

    use Illuminate\Support\Fluent;
    use Illuminate\Support\Collection;
    
    // Mocking data to meet your requirements.
    // Wrapping attributes inside fluent object,
    // so we'll have almost same object like Eloquent model
    $orders = new Collection([
        new Fluent([
            'qty' => 2,
            'price' => 200,
            'item' => new Fluent([
                'id' => 1,
                'price' => 100,
                'title' => 'Black Hoodie',
                'img' => 'https://s3.amazonaws.com/bucket/black-hoodie.jpg',
                'description' => 'Plain Black Hoodie.',
            ])
        ]),
        new Fluent([
            'qty' => 2,
            'price' => 200,
            'item' => new Fluent([
                'id' => 2,
                'price' => 100,
                'title' => 'Green Hoodie',
                'img' => 'https://s3.amazonaws.com/bucket/green-hoodie.jpg',
                'description' => 'Plain Green Hoodie.',
            ])
        ]),
        new Fluent([
            'qty' => 1,
            'price' => 100,
            'item' => new Fluent([
                'id' => 2,
                'price' => 100,
                'title' => 'Green Hoodie',
                'img' => 'https://s3.amazonaws.com/bucket/green-hoodie.jpg',
                'description' => 'Plain Green Hoodie.',
            ])
        ]),
        new Fluent([
            'qty' => 1,
            'price' => 100,
            'item' => new Fluent([
                'id' => 1,
                'price' => 100,
                'title' => 'Black Hoodie',
                'img' => 'https://s3.amazonaws.com/bucket/black-hoodie.jpg',
                'description' => 'Plain Black Hoodie.',
            ])
        ])
    ]);
    
    // Here's something you might interested
    $result = $orders->groupBy('item.id')
        ->map(function ($orders, $itemId) {
            return new Fluent([
                'qty' => $orders->sum('qty'), // calculating quantity
                'price' => $orders->sum('price'), // calculating total price
                'item' => $orders->first()->item // leave the item as it is
            ]);
        });
    
    // You may evaluate the result here
    dd($result);
    

    更新

    更多“原始”示例:

    use Illuminate\Support\Collection;
    
    $orderOne = [
        'id' => 1,
        'price' => 100,
        'title' => 'Black Hoodie',
        'img' => 'https://s3.amazonaws.com/bucket/black-hoodie.jpg',
        'description' => 'Plain Black Hoodie.',
    ];
    
    $orderTwo = [
        'id' => 2,
        'price' => 100,
        'title' => 'Green Hoodie',
        'img' => 'https://s3.amazonaws.com/bucket/green-hoodie.jpg',
        'description' => 'Plain Green Hoodie.',
    ];
    
    $orders = new Collection([
        [
            'qty' => 2,
            'price' => 200,
            'item' => $orderOne
        ],
        [
            'qty' => 2,
            'price' => 200,
            'item' => $orderTwo
        ],
        [
            'qty' => 1,
            'price' => 100,
            'item' => $orderTwo
        ],
        [
            'qty' => 1,
            'price' => 100,
            'item' => $orderOne
        ]
    ]);
    
    $result = $orders->groupBy('item.id')
        ->map(function ($orders, $itemId) {
            return [
                'qty' => $orders->sum('qty'),
                'price' => $orders->sum('price'),
                'item' => $orders->first()['item']
            ];
        });
    
    dd($result);
    

    【讨论】:

    • ... 就像您的简单而巧妙的解决方案让我感到无脑。至少我可以说我是在正确的方向哈哈!谢谢!
    猜你喜欢
    • 2016-09-10
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 2015-05-08
    • 2016-11-19
    • 1970-01-01
    • 2012-08-06
    • 2019-03-31
    相关资源
    最近更新 更多