Reputation: 655
I have a multidimensional array that looks like such:
Array
(
[0] => Array
(
[email] => [email protected]
[added] => style-narcotics
)
[1] => Array
(
[email] => [email protected]
[added] => style-edm
)
[2] => Array
(
[email] => [email protected]
[added] => style-codeine
)
[3] => Array
(
[email] => [email protected]
[added] => style-food
)
)
I want to merge all the inner arrays combining the "added" key like such:
Array
(
[0] => Array
(
[email] => [email protected]
[added] => array(
[0]=>style-narcotics
[1]=>style-edm
)
)
[1] => Array
(
[email] => [email protected]
[added] => array(
[0]=>style-codeine
[1]=>style-food
)
)
I have tried merge array recursive in different forms and call_user_func but it doesnt cut it. Any advice? Thanks!
Upvotes: 2
Views: 327
Reputation: 72226
A simple solution that uses array_reduce()
:
$output = array_reduce(
$input,
function (array $carry, array $item) {
$email = $item['email'];
if (! isset($carry[$email])) {
// It's a new email, make room for it in the output
$carry[$email] = array('email' => $email, 'added' => array(), );
}
// Add the value of $item['added'] into the existing array
$carry[$email]['added'][] = $item['added'];
return $carry;
},
array()
);
// Output is indexed by email addresses. If you need numeric keys then...
$output = array_values($output);
The same logic as above but with an explicit iteration over the input array (the code is a couple of lines shorter):
$output = array();
foreach ($input as $item) {
$email = $item['email'];
if (! isset($carry[$email])) {
// It's a new email, make room for it in the output
$carry[$email] = array('email' => $email, 'added' => array(), );
}
// Add the value of $item['added'] into the existing array
$carry[$email]['added'][] = $item['added'];
}
$output = array_values($output);
Upvotes: 1
Reputation: 92854
I would call it "grouping", but not "merging".
Use the following approach with array_walk
and array_values
functions:
$grouped = [];
// $arr is your initial array
array_walk($arr, function($v) use (&$grouped){
if (array_key_exists($v["email"], $grouped)) {
$grouped[$v["email"]]["added"][] = $v["added"];
} else {
$v["added"] = [$v["added"]];
$grouped[$v["email"]] = $v;
}
});
print_r(array_values($grouped));
The output:
Array
(
[0] => Array
(
[email] => [email protected]
[added] => Array
(
[0] => style-narcotics
[1] => style-edm
)
)
[1] => Array
(
[email] => [email protected]
[added] => Array
(
[0] => style-codeine
[1] => style-food
)
)
)
Upvotes: 3