PHP merge(单深度)基于第一个索引(日期)递归


PHP merge (single depth) recursive based on first index (date)

我已经搜索了很多,但找不到完全相似的问题。内置函数在PHP不做什么我正在寻找。注意:array_merge_recursive(…)很接近,但是没有保留索引。

我有例如PHP数组(json可视化):

[
    ["1-6-13", 10],
    ["30-6-13", 13],
    ["20-9-13", 28]
]

:

[
    ["18-2-13", 7],
    ["30-6-13", 9]
]

我想合并这两个,基于他们的日期。然而,并不是每个日期都匹配,重要的是数组1的值将在索引1上,数组2的值必须附加到索引2。例如,不存在的值必须为null。

所以期望的结果看起来像:

[
    ["18-2-13", null, 7],
    ["1-6-13", 10, null],
    ["30-6-13", 13, 9],
    ["20-9-13", 28, null]
]

我希望有人能帮助我!

首先可以像这样获取所有日期的集合:

$dates = array_merge(array_map('reset', $data1), array_map('reset', $data2));

这个集合包含重复项,但我们并不真正关心(如果这是一个问题,我们可以用array_unique删除它们)。

旁注:如果运行PHP>= 5.5,最好使用array_column($arr, 0)而不是array_map('reset', $arr)

然后将其投影到一个数组的数组中,使用日期作为键:

$result = array_fill_keys($dates, array(null, null, null));

并填入数据:

foreach($data1 as $pair) {
    list($date, $num) = $pair;
    $result[$date][0] = $date;
    $result[$date][1] = $num;
}
foreach($data2 as $pair) {
    list($date, $num) = $pair;
    $result[$date][0] = $date;
    $result[$date][2] = $num;
}

当然,以上可以很容易地推广到任意数量的带有循环的数组。

最后,如果您希望对$result进行数字索引,则丢失用作键的日期:

$result = array_values($result);

查看效果

您可以这样做。这样做的好处是,您只需循环遍历数组一次:

$dates = array();
foreach( $array1 as $val ) {
    $dates[$val[0]] = array( $val[0], $val[1], null );
}
foreach( $array2 as $val) {
    $dates[$val[0]][0] = $val[0];
    $dates[$val[0]][1] = isset( $dates[$val[0]][1] ) ? $dates[$val[0]][1] : null;
    $dates[$val[0]][2] = $val[1];
}