如何高效合并两个(或多个)具有相同键的关联数组

1 投票
3 回答
1345 浏览
提问于 2025-04-16 12:34

更一般来说,假设我们有两个长度不同的列表,它们有一个共同的属性:

list1: {
         {"orderID":1234, "FirstName":"shaheeb", "LastName":"roshan"},
         {"orderID":9183, "FirstName":"robert", "LastName":"gibbons"},
         {"orderID":2321, "FirstName":"chester"},
       }
list2: {
         {"orderID":1234, "cell":"555-555-5555", "email":"roshan@fake.com"},
         {"orderID":2321, "email":"chester@fake.com"},
       }

我希望把它们合并成:

list3: {
         {"orderID":1234, "FirstName":"shaheeb", "LastName":"roshan", "cell":"555-555-5555", "email":"roshan@fake.com"},
         {"orderID":9183, "FirstName":"robert", "LastName":"gibbons"},
         {"orderID":2321, "FirstName":"chester", "email":"chester@fake.com"},
       }

我主要是做PHP开发的,想出了以下方法:

function mergeArrays($a1, $a2) {
    $larger = (count($a1) > count($a2)) ? $a1 : $a2;
    $smaller = ($larger == $a1) ? $a2 : $a1;
    $combinedArray = array();
    foreach ($larger AS $key=>$largerSet) {
        $combinedRow = array();
        if (isset ($smaller[$key]) ) {
            $combinedRow = $largerSet + $smaller[$key];
            $combinedArray[$key] = $combinedRow;
        }else {
            $combinedArray[$key] = $largerSet;
        }
    }
    return ($combinedArray);
}

如果用以下内容进行测试:

$array1 = array("12345"=>array("OrderID"=>12345, "Apt"=>"blue"));
$array2 = array(
                "12345"=>array("OrderID"=>12345, "AnotherCol"=>"Goons", "furtherColumns"=>"More Data"),
                "13433"=>array("OrderID"=>32544, "Yellow"=>"Submarine")
            );

mergeArrays($array1, $array2) 的输出结果是:

array(2) {
  [12345]=>
  array(4) {
    ["OrderID"]=>
    int(12345)
    ["AnotherCol"]=>
    string(5) "Goons"
    ["furtherColumns"]=>
    string(9) "More Data"
    ["Apt"]=>
    string(4) "blue"
  }
  [13433]=>
  array(2) {
    ["OrderID"]=>
    int(32544)
    ["Yellow"]=>
    string(9) "Submarine"
  }
}

但我觉得这并不是最优雅的解决方案。比如说,我应该能够合并任意数量的数组。我不太确定该怎么做到这一点。而且,仅从那段代码来看,我很确定还有更有效的方法来满足这个需求。

作为一个学习的机会,我很好奇Python的专家们是否会借此机会来给我们PHP开发者上课 :)。顺便说一下,我也想知道Excel/VBA是否能处理这个问题。其实我最开始就是想用Excel来解决这个问题,因为我想“肯定Excel能处理列表!”

我完全知道在Stack Overflow上有很多类似的问题。我看过好几个,还是觉得应该在这里试试我的版本。

非常感谢你的想法。

谢谢!

SR

3 个回答

1

其实,你可以用 array_merge_recursive 这个函数来替代你的函数。

2

这是一个通用的解决方案,可以合并任意数量的字典(或者字典的列表——如果你有多个列表,只需在调用这个函数之前把它们加在一起即可):

from collections import defaultdict

def merge_dicts_by_key(key, *dicts):
    return reduce(lambda acc,val: acc[val[key]].update(val) or acc,
                  dicts,
                  defaultdict(dict))

调用方法如下:

merge_dicts_by_key('orderId', dict1, dict2, dict3)

或者,如果你有字典的列表:

merge_dicts_by_key('orderId', *list_of_dicts)
merge_dicts_by_key('orderId', *(list1 + list2))
4

这是一个关于在Python中处理多个列表的通用解决方案,适用于任意数量的列表:

orders = defaultdict(dict)
for order_list in order_lists:
    for order in order_list:
        orders[order['orderID']].update(order)

你可以在网上看到它的运行效果:ideone

撰写回答