Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel map(): How to alter objects and arrays?

I have a multidimensional collection. I want to iterate it and alter some of its child objects and arrays using the map() function: https://laravel.com/docs/5.1/collections#method-map

Sample content:

[
    {
        'address': 'Somestreet 99'
        'orders': [
            {'id': 11},
            {'id': 67}
        ]
    }
]

Example

  $deliveries = $delivery_addresses->map(function($delivery_address){
     $orders = $delivery_address->orders->filter(function($order){
        return $order->id == 67;
     });

     $delivery_address['address'] = 'A different street 44'
     $delivery_address['orders'] = $orders;
     $delivery_address['a_new_attribute'] = 'Some data...';

     return $delivery_address;
  });

Expected result:

[
    {
        'address': 'A different street 44'
        'orders': [
            {'id': 67}
        ],
        'a_new_attribute': 'Some data...;
    }
]

The result is that only string type variables will be changed. Any arrays or objects will stay the same. Why is this and how to get around it? Thanks! =)

like image 695
MikaelL Avatar asked Jan 15 '16 09:01

MikaelL


2 Answers

collect($deliver_addresses)->map(function ($address) use ($input) {

    $address['id']              = $input['id'];
    $address['a_new_attribute'] = $input['a_new_attribute'];

    return $address;

});
like image 181
Mayuri Pansuriya Avatar answered Oct 13 '22 09:10

Mayuri Pansuriya


Addressing your recent edits, try this:

$deliveries = $deliver_addresses->map(function($da) {
    $orders = $da->orders->filter(function($order) {
        return $order->id == 67;
    });

    $da->unused_attribute = $orders->all();

    return $da;
});

What the case most likely is here is that you are correctly overwriting that attribute. Then when you are attempting to access it Laravel is querying the orders() relationship and undoing your changes. As far as Laravel is concerned these are the same:

$delivery_address->orders;
$delivery_address['orders'];

This is why the changes are only working on objects. If you want to save that permanently then actually save it, if not use a temporary attribute to contain that data.

like image 36
Sturm Avatar answered Oct 13 '22 10:10

Sturm