我有一个看起来像这样的多维数组:
Array
(
[0] => Array
(
[email] => email1@gmail.com
[added] => style-narcotics
)
[1] => Array
(
[email] => email1@gmail.com
[added] => style-edm
)
[2] => Array
(
[email] => email2@gmail.com
[added] => style-codeine
)
[3] => Array
(
[email] => email2@gmail.com
[added] => style-food
)
)
我想合并所有内部数组,组合"添加"的密钥,比如:
Array
(
[0] => Array
(
[email] => email1@gmail.com
[added] => array(
[0]=>style-narcotics
[1]=>style-edm
)
)
[1] => Array
(
[email] => email2@gmail.com
[added] => array(
[0]=>style-codeine
[1]=>style-food
)
)
我尝试过不同形式的递归合并数组和call_user_func,但它并不能解决问题。有什么建议吗?谢谢
我称之为"分组",而不是"合并"
对array_walk
和array_values
函数使用以下方法:
$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));
输出:
Array
(
[0] => Array
(
[email] => email1@gmail.com
[added] => Array
(
[0] => style-narcotics
[1] => style-edm
)
)
[1] => Array
(
[email] => email2@gmail.com
[added] => Array
(
[0] => style-codeine
[1] => style-food
)
)
)
使用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);
与上面的逻辑相同,但在输入数组上有一个显式迭代(代码短了几行):
$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);