用缺失的键填充多维数组

3
我有以下多维数组。我必须按照它的外观创建键,以便将它们相应地分组。
Array
(
    [Oranges] => Array
        (
            [Name] => Oranges
            [l.VA123] => 17
            [l.MA123] => 12
            [l.GA123] => 9
            [l.CT123] => 5
        )

    [Apple] => Array
        (
            [Name] => Apple
            [l.CA123] => 13
        )

    [Grapes] => Array
        (
            [Name] => Grapes
            [l.WI123] => 8
            [l.FL123] => 5
        )
)

然而,我需要所有的子数组都有相同的键。缺失的键应该填充为0。最终的数组应该像下面这样,以便所有的子数组具有相等的长度。

    Array
(
    [Oranges] => Array
        (
            [Name] => Oranges
            [l.VA123] => 17
            [l.MA123] => 12
            [l.GA123] => 9
            [l.CT123] => 5
            [l.CA123] => 0
            [l.WI123] => 0
            [l.FL123] => 0
        )

    [Apple] => Array
        (
            [Name] => Apple
            [l.CA123] => 13
            [l.WI123] => 0
            [l.FL123] => 0
            [l.VA123] => 0
            [l.MA123] => 0
            [l.GA123] => 0
            [l.CT123] => 0
        )

    [Grapes] => Array
        (
            [Name] => Grapes
            [l.WI123] => 8
            [l.FL123] => 5
            [l.CA123] => 0
            [l.VA123] => 0
            [l.MA123] => 0
            [l.GA123] => 0
            [l.CT123] => 0
        )
)

子数组中使用 NameGene 关键字? - u_mulder
3个回答

4
你需要一个简单的 + 运算符。根据手册

加号运算符返回右侧数组附加到左侧数组; 对于在两个数组中都存在的键,将使用左侧数组中的元素,并忽略右侧数组中匹配的元素。

$items = Array
(
    'Oranges' => Array
        (
            'Name' => 'Oranges',
            'l.VA123' => 17,
            'l.MA123' => 12,
            'l.GA123' => 9,
            'l.CT123' => 5,
        ),

    'Apple' => Array
        (
            'Name' => 'Apple',
            'l.CA123' => 13,
        ),

    'Grapes' => Array
        (
            'Name' => 'Grapes',
            'l.WI123' => 8,
            'l.FL123' => 5,
        ),
);

// static keys
$keys = [
    'l.VA123' => 0,
    'l.MA123' => 0,
    'l.GA123' => 0,
    'l.CT123' => 0,
    'l.CA123' => 0,
    'l.WI123' => 0,
    'l.FL123' => 0,
];


// keys generated from source array, tricky approach
$keys = array_fill_keys(
    // here we merge all elements of `$items` into one array
    // as keys are repeated - you definitely got all keys that
    // can be in `$items`, `array_keys` will give you these keys
    // `array_fill_keys` will create array where key is what you need
    // and value is 0.
    array_keys(call_user_func_array('array_merge', $items)),
    0
);

// keys generated from source array, SIMPLE approach
$keys = [];
foreach ($items as $item) {
    foreach ($item as $k => $v) {
        if ($k != 'Name') {
            $keys[$k] = 0;
        }
    }
}

foreach ($items as &$item) {
    $item = $item + $keys;
}
print_r($items);

我更新了Q。它不是Name。新的数组需要具有丢失键和值0。 - user5249203
我把键从“Gene”改成了“Name”,但这并不重要。我的答案仍然是一样的。 - u_mulder
谢谢你的回答。我不想手动创建新键。有没有办法可以从多维数组中创建键列表? - user5249203
还添加了一种简单的方法,不需要太多的注释。 - u_mulder
1
foreach 控制结构提供了遍历数组的简单方式。 foreach 仅能够应用于数组和对象。如果尝试应用于其他类型的变量会产生错误。有两种语法:foreach (array_expression as $value) statementforeach (array_expression as $key => $value) statement第一种语法只对数组中的值感兴趣,第二种除了对值感兴趣以外,还对键相应的元素感兴趣。 - u_mulder

2

可能有人能想出更有效率的方法,但如果没有你想要的键列表,我认为你需要对数组进行几次遍历:

<?php
$fruits = [
    "Oranges"=>["Name"=>"Oranges", "l.VA123"=>17, "l.MA123"=>12, "1.GA123"=>9, "1.CT123"=>5],
    "Apple"=>["Name"=>"Apple", "1.CA123"=>13],
    "Grapes"=>["Name"=>"Grapes", "1.WI123"=>8, "1.FL123"=>5]
];
$keys = [];
foreach ($fruits as $fruit) {
    unset($fruit["Name"]);
    $keys = array_merge($keys, array_keys($fruit));
}
$keys = array_fill_keys(array_unique($keys), 0);

foreach ($fruits as &$fruit) {
    $fruit = array_merge($keys, $fruit);
}
print_r($fruits);

1

由于所有键和默认值都是“已知的”,因此创建一个关联数组,使用foreach()并通过引用修改行,并使用联合赋值(组合)运算符。这将允许原始值覆盖默认值。

代码:(演示)

$keys = [
    'l.VA123' => 0,
    'l.MA123' => 0,
    'l.GA123' => 0,
    'l.CT123' => 0,
    'l.CA123' => 0,
    'l.WI123' => 0,
    'l.FL123' => 0,
];

foreach ($items as &$row) {
    $row += $keys;
}
var_export($items);

如果要让键值对始终保持一致的位置,请使用array_replace()array_merge()代替联合赋值运算符。
代码: (演示)
foreach ($items as &$row) {
    $row = array_replace($keys, $row);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接