在多维数组php的内部数组上合并递归

时间:2016-04-15 19:48:37

标签: php multidimensional-array merge

我有一个看起来像这样的多维数组:

 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进行合并数组递归,但它并没有削减它。有什么建议?谢谢!

2 个答案:

答案 0 :(得分:3)

我称之为“分组”,但不是“合并” 对array_walkarray_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
                )
        )
)

答案 1 :(得分:1)

使用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);