Home > Software engineering >  Merge arrays in laravel including keys
Merge arrays in laravel including keys

Time:01-18

I have 2 arrays and I want to merge them. (I can merge them) but I also need to include their unique keys in merged results and that part I cannot achieve.

sample

$prices = [
    ['112802' => "500000"],
    ['113041' => "1000000"],
];

$notes = [
    ['112802' => "note 2"],
    ['113041' => "note 1"],
];

$collection = collect($prices);
$zipped = $collection->zip($notes);
$zipped->toArray();

Unique keys are 112802 and 113041.

When I merge my array all I get is this:

[
  [
    "1000000",
    "note 1"
  ],
  [
    "500000",
    "note 2"
  ]
]

What I'm looking for is like this:

[
    [
        "id" => "112802",
        "price" => "500000",
        "note" => "note 2",
    ],
    [
        "id" => "113041",
        "price" => "1000000",
        "note" => "note 1",
    ]
}]

any suggestion?

CodePudding user response:

This does what you want with the data you provide.

NOTE it will only work if your 2 arrays are the same size and the the keys are in the same order.

If this data comes from a database, it is likely it could have been produced in the format you actually wanted rather than having to fiddle with the data post fetch.

$prices = [
    ['112802' => "500000"],
    ['113041' => "1000000"],
];

$notes = [
    ['112802' => "note 2"],
    ['113041' => "note 1"],
];

$new = [];
foreach ($prices as $i=>$pr){
    $k = key($pr);
    $new[] = [  'id' => $k, 
                'price' => $pr[$k], 
                'note' => $notes[$i][$k] ];
}
print_r($new);

RESULT

Array
(
    [0] => Array (
            [id] => 112802
            [price] => 500000
            [note] => note 2
        )

    [1] => Array (
            [id] => 113041
            [price] => 1000000
            [note] => note 1
        )
)

CodePudding user response:

Here's another solution using some of Laravel's Collection methods.
It's not the most elegant, but it can be a starting point for you.

$prices = collect([
    ['112802' => "500000"],
    ['113041' => "1000000"],
])->mapWithKeys(function($item) {
    // This assumes that the key will always be the ID and the first element is the price.
    // Everythng else for each element will be ignored.
    $id = array_keys($item)[0];
    return [$id => ["id" => $id, "price" => reset($item)]];
});

$notes = collect([
    ['112802' => "note 2"],
    ['113041' => "note 1"],
])->mapWithKeys(function($item) {
    $id = array_keys($item)[0];
    return [$id => ["id" => $id, "note" => reset($item)]];
});

$result = $prices->zip($notes)->map(function ($item) {
    // Feel free to call `toArray()` here if you don't want a Collection.
    return collect($item)->mapWithKeys(function ($a) { return $a; });
});

Below is the $result (called using dd()).

Illuminate\Support\Collection {#1886 ▼
  #items: array:2 [▼
    0 => Illuminate\Support\Collection {#1888 ▼
      #items: array:3 [▼
        "id" => 112802
        "price" => "500000"
        "note" => "note 2"
      ]
    }
    1 => Illuminate\Support\Collection {#1889 ▼
      #items: array:3 [▼
        "id" => 113041
        "price" => "1000000"
        "note" => "note 1"
      ]
    }
  ]
}

It's achieved by extracting the ID so that the zip can join there, but then we need a little hack with the map and mapWithKeys in the $result.
That's just because otherwise each element in $result will still have two separate arrays for $prices and $notes.

  • Related