PHP - 合并多维数组中的键

时间:2011-02-10 17:30:26

标签: php multidimensional-array

我有一个像下面的示例一样构造的大型多维数组。

[0] => Array
    (
        [name] => SMITH
        [status] => Incomplete
        [count] => 2
    )

[1] => Array
    (
        [name] => SMITH
        [status] => Complete
        [count] => 2
    )

[2] => Array
    (
        [name] => HUGHES
        [status] => Incomplete
        [count] => 3
    )

[3] => Array
    (
        [name] => HUGHES
        [status] => Complete
        [count] => 1
    )

我想要的是一个看起来像这样的新数组 -

[0] => Array
    (
        [name] => SMITH
        [Complete] => 2
        [Incomplete] => 2
    )

[1] => Array
    (
        [name] => HUGHES
        [Complete] => 1
        [Incomplete] => 3
    )

我是PHP的新手,我确实意识到我需要遍历原始数组,但任何帮助都会受到赞赏。

3 个答案:

答案 0 :(得分:2)

$original = array( array ( 'name' => 'SMITH',
                           'status' => 'Incomplete',
                           'count' => 2
                         ),
                   array ( 'name' => 'SMITH',
                           'status' => 'Complete',
                           'count' => 2
                         ),

                   array ( 'name' => 'HUGHES',
                           'status' => 'Incomplete',
                           'count' => 3
                         ),
                   array ( 'name' => 'HUGHES',
                           'status' => 'Complete',
                           'count' => 1
                         ),
                 );

// initialise our new array
$newArray = array();
// loop through each entry from the original array in turn
foreach($original as $entry) {
    // temporarily use the name as the key for our new array (we'll reset to a numeric later)
    $name = $entry['name'];
    $newArray[$name]['name'] = $name;
    //  test if we have multiple entries for the same name/status
    if (isset($newArray[$name][$entry['status']])) {
        $newArray[$name][$entry['status']] += $entry['count'];
    } else {
        $newArray[$name][$entry['status']] = $entry['count'];
    }
}

//  Reset top-level keys to numerics
$newArray = array_values($newArray);

echo '<pre>';
var_dump($newArray);
echo '</pre>';

答案 1 :(得分:2)

我会把这分为三个步骤。

第一步:改变这个

[0] => Array
    (
        [name] => SMITH
        [status] => Incomplete
        [count] => 2
    )

[1] => Array
    (
        [name] => SMITH
        [status] => Complete
        [count] => 2
    )

进入这个

[0] => Array
    (
        [name] => SMITH
        [Incomplete] => 2
    )

[1] => Array
    (
        [name] => SMITH
        [Complete] => 2
    )

可以通过以下方式完成

$data = array_map($data, function($d) {
    return array('name' => $d['name'], $d['status'] => $d['count']);
});

第二步:

我见过许多人询问这个阶段的问题,通常是在处理数据库查询结果集时。基本问题是,不是按行号索引记录,而是要根据每条记录包含的一些数据索引记录。所以,这是一个通用函数......

function make_index($array, $key) {
    foreach ($array as $a) {
        $r = &$reindexed[$a[$key]];
        $r = array_merge((array)$r, $a);
    }
    return $reindexed;
}

按照第一步的结果行事,假设我们将其称为$data = make_index($data, "name");,我们将到达

Array
(
    [SMITH] => Array
        (
            [name] => SMITH
            [Incomplete] => 2
            [Complete] => 2
        )

)

第三步:

现在你想回到数字索引,这很容易实现。

$data = array_values($data);

给出

Array
(
    [0] => Array
        (
            [name] => SMITH
            [Incomplete] => 2
            [Complete] => 2
        )

)

结论:

将数据集转换分解为婴儿步骤非常有用。通过这样做,您可以在不同的问题中重复使用各个步骤。此外,对于复杂的更改,更容易找到解决方案,或者在编写代码后理解代码。

关于第二步的说明:

在第二步中,我提供了一个“通用”函数,但实际上,array_merge完成的合并将不适用于大多数情况。具体来说,查询结果包含包含所有相同键的记录,并且简单的重写不太可能是所需的聚合方法。这是克服此限制的另一种变体。

function make_index($array, $key, $M) {
    foreach ($array as $a) {
        $r = &$reindexed[$a[$key]];
        $r = $M((array)$r, $a);
    }
    return $reindexed;
}

// ex: $data = make_index($data, "name", function($e1, $e2){
//    return array_merge($e1, $e2);
// });
// equiv to: $data = make_index($data, "name", 'array_merge');

答案 2 :(得分:0)

这样的事情就是我要去的方式:

$new = array();
foreach($original as $entity)
{
    if(!isset($new[$entity["name"]]))
    {
        $new[$entity["name"]] = array(
            "name" => $entity["name"],
            "Complete" => 0,
            "Incomplete" => 0
        );
    }
    $new[$entity["name"]][$entity["status"]] += $entity["count"];
}

print_r($new);

使用上面的数组示例,请注意数组中的区分大小写,这会产生影响。

出口就像这样:

Array
(
    [SMITH] => Array
        (
            [name] => SMITH
            [Complete] => 2
            [Incomplete] => 2
        )

    [HUGHES] => Array
        (
            [name] => HUGHES
            [Complete] => 1
            [Incomplete] => 3
        )

)

并且有一个实时代码演示@ http://codepad.org/H099lulS