Merge multi-dimensional arrays with common id

94 views Asked by At

I have two multi-dimensional arrays:

First array Pizzas:

0 => array:2 [▼
    "pizza_id" => 11
    "pizza_name" => "Hawaï"
]
1 => array:2 [▼
    "pizza_id" => 12
    "pizza_name" => "Tonno"
]
2 => array:2 [▼
    "pizza_id" => 13
    "pizza_name" => "Surprise"
]

Second array Ingredients:

0 => array:4 [▼
    "pizza_id" => 11
    "ingredient_one" => "Ananas"
    "ingredient_two" => "Onion"
    "ingredient_three" => "Ham"
]
1 => array:4 [▼
    "pizza_id" => 12
    "ingredient_one" => "Tuna"
    "ingredient_two" => "Onion"
    "ingredient_three" => null
]

I want to merge these two arrays linking them by pizza_id. One of the Pizza Ids has no matching array for ingredients (the ingredients are unknown) so for this Pizza I want to set ingredients to null and get the next array:

New array PizzaAndIngredients:

0 => array:5 [▼
    "pizza_cid" => 11
    "pizza_name" => "Hawaï"
    "ingredient_one" => "Ananas"
    "ingredient_two" => "Onion"
    "ingredient_three" => "Ham"
]
1 => array:5 [▼
    "pizza_id" => 12
    "pizza_name" => "Tonno"
    "ingredient_one" => "Tuna"
    "ingredient_two" => "Onion"
    "ingredient_three" => null
]
2 => array:5 [▼
    "pizza_id" => 13
    "pizza_name" => "Surprise"
    "ingredient_one" => null
    "ingredient_two" => null
    "ingredient_three" => null
]

I have been fiddling around with array_merge, foreach, etc but can not get the array. The alternative is to build a new query and left-join pizzas and ingredients but in real life the arrays are much more complicated and this would mean duplicating a lot of code.

I was hoping for a more efficient solution of merging the two multi-dimensional array's.

My last attempt is:

$PizzaAndIngredients = array();
foreach ($pizzas as $key => $values) {
    $PizzaAndIngredients[$key] = array_merge($ingredients, $values);
}
1

There are 1 answers

3
AbraCadaver On BEST ANSWER

When you fetch the rows from the query results you can set the array keys equal to the pizza_id, or re-index them by the pizza_id:

$pizza       = array_column($pizza, null, 'pizza_id');
$ingredients = array_column($ingredients, null, 'pizza_id');

Then just create a default array of nulls to use if the $ingredients don't exist and then merge $ingredients values with the $pizza values:

//get an ingredient array
$temp    = reset($ingredients);
//combine keys and an array of nulls
$default = array_combine(array_keys($temp),
                         array_fill(0, count($temp), null));

foreach($pizza as $id => $p_values) {
    //check if $ingredients[$id] exists, if not use the default
    $i_values    = isset($ingredients[$id]) ? $ingredients[$id] : $default;
    //you can also use just $result[] if you don't need the pizza_id as key
    $result[$id] = array_merge($i_values, $p_values); 
}