skip to Main Content

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?

2

Answers


  1. 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
            )
    )
    
    Login or Signup to reply.
  2. 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()).

    IlluminateSupportCollection {#1886 ▼
      #items: array:2 [▼
        0 => IlluminateSupportCollection {#1888 ▼
          #items: array:3 [▼
            "id" => 112802
            "price" => "500000"
            "note" => "note 2"
          ]
        }
        1 => IlluminateSupportCollection {#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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search