如何通过 Map 的特定键合并/加入两个 Map 列表?

Posted

技术标签:

【中文标题】如何通过 Map 的特定键合并/加入两个 Map 列表?【英文标题】:How to merge/join two List of Map by specific key of Map? 【发布时间】:2021-02-25 15:56:07 【问题描述】:

如何通过特定键合并两个 List>? 就像,我有两个 List>,其中除了“id”之外的所有键都是不同的,我想根据键“id”加入它们。

例如:

List> 钱包和List> 币种操作前

List<Map<String, dynamic>> Wallet = [
  
    "id": 1,
    "value": 153030
  ,
  
    "id": 2,
    "value": 817831
  ,
  
    "id": 3,
    "value": 25
  ,
  
    "id": 4,
    "value": 660
  ,
  
    "id": 5,
    "value": 132
  ,
  
    "id": 7,
    "value": 145
  
];

List<Map<String, dynamic>> Currencies = [
  
    "id": 1,
    "name": "coin",
    "desc": "Dummytext.",
    "order": 101,
    "icon": "https://icon1.png"
  ,
  
    "id": 2,
    "name": "karma",
    "desc": "Dummytext.",
    "order": 102,
    "icon": "https://icon2.png"
  ,
  
    "id": 3,
    "name": "laurel",
    "desc": "Dummytext.",
    "order": 104,
    "icon": "https://icon3.png"
  ,
  
    "id": 4,
    "name": "diamonds",
    "desc": "Dummytext.",
    "order": 100,
    "icon": "https://icon4.png"
  ,
  
    "id": 5,
    "name": "tears",
    "desc": "Dummytext.",
    "order": 402,
    "icon": "https://icon5.png"
  ,
  
    "id": 6,
    "name": "shard",
    "desc": "Dummytext.",
    "order": 409,
    "icon": "https://icon6.png"
  ,
  
    "id": 7,
    "name": "relict",
    "desc": "Dummytext.",
    "order": 400,
    "icon": "https://icon7.png"
  ,
  
    "id": 9,
    "name": "seal",
    "desc": "Dummytext.",
    "order": 403,
    "icon": "https://icon9.png"
  ,
  
    "id": 10,
    "name": "silver",
    "desc": "Dummytext.",
    "order": 405,
    "icon": "https://icon10.png"
  
];

合并后的列表我要找的操作后

List<Map<String, dynamic>> ExtendedWallet = [
  
    "id": 1,
    "value": 153030,
    "name": "coin",
    "desc": "Dummytext.",
    "order": 101,
    "icon": "https://icon1.png"
  ,
  
    "id": 2,
    "value": 817831,
    "name": "karma",
    "desc": "Dummytext.",
    "order": 102,
    "icon": "https://icon2.png"
  ,
  
    "id": 3,
    "value": 25,
    "name": "laurel",
    "desc": "Dummytext.",
    "order": 104,
    "icon": "https://icon3.png"
  ,
  
    "id": 4,
    "value": 660,
    "name": "diamonds",
    "desc": "Dummytext.",
    "order": 100,
    "icon": "https://icon4.png"
  ,
  
    "id": 5,
    "value": 132,
    "name": "tears",
    "desc": "Dummytext.",
    "order": 402,
    "icon": "https://icon5.png"
  ,
  
    "id": 7,
    "value": 145,
    "name": "relict",
    "desc": "Dummytext.",
    "order": 400,
    "icon": "https://icon7.png"
  
];

请注意,“id”在 Wallet 中 not 的 Currencies 地图将不会被使用,将被跳过。

希望你们能得到我的意见,并能帮助我解决这个问题!

【问题讨论】:

【参考方案1】:

你可以使用singleWhere找到cross id,然后使用map进行合并,这里修复的问题是飞镖垫here

  List<Map<String, dynamic>> wallet = [
    "id": 1, "value": 153030,
    "id": 2, "value": 817831,
    "id": 3, "value": 25,
    "id": 4, "value": 660,
    "id": 5, "value": 132,
    "id": 7, "value": 145
  ];

  List<Map<String, dynamic>> currencies = [
    
    "id": 1,
    "name": "coin",
    "desc": "Dummytext.",
    "order": 101,
    "icon": "https://icon1.png"
  ,
  
    "id": 2,
    "name": "karma",
    "desc": "Dummytext.",
    "order": 102,
    "icon": "https://icon2.png"
  ,
  
    "id": 3,
    "name": "laurel",
    "desc": "Dummytext.",
    "order": 104,
    "icon": "https://icon3.png"
  ,
  
    "id": 4,
    "name": "diamonds",
    "desc": "Dummytext.",
    "order": 100,
    "icon": "https://icon4.png"
  ,
  
    "id": 5,
    "name": "tears",
    "desc": "Dummytext.",
    "order": 402,
    "icon": "https://icon5.png"
  ,
  
    "id": 6,
    "name": "shard",
    "desc": "Dummytext.",
    "order": 409,
    "icon": "https://icon6.png"
  ,
  
    "id": 7,
    "name": "relict",
    "desc": "Dummytext.",
    "order": 400,
    "icon": "https://icon7.png"
  ,
  
    "id": 9,
    "name": "seal",
    "desc": "Dummytext.",
    "order": 403,
    "icon": "https://icon9.png"
  ,
  
    "id": 10,
    "name": "silver",
    "desc": "Dummytext.",
    "order": 405,
    "icon": "https://icon10.png"
  
  ];

  var result = currencies.map((e) 
    Map<String, dynamic> founded =
        wallet.singleWhere((w) => w['id'] == e['id'], orElse: ()return null;);

    if (founded != null) 
      e.addEntries(founded.entries);
      return e;
     else 
      return null;
    
  ).toList();

  print(result);


【讨论】:

好吧,不知何故它不起作用。最后尝试使用您的打印语句验证输出,但它什么也没做。此外,“as Map”被识别为“不必要的演员表”。任何其他建议可能是什么问题? 我删除了不必要的演员表,并在 dartpad.dev 上进行了测试,并且正在工作 : Bad state: No elementError: Bad state: 在 dartpad.dev 中没有元素发生了更多数据(来自我上面的示例) 我发现问题让我解决它【参考方案2】:

您可以使用此代码获得所需的结果

import 'dart:convert';
void main()   
  List<Map<String, dynamic>> Wallet = [
  
    "id": 1,
    "value": 153030
  ,
  
    "id": 2,
    "value": 817831
  ,
  
    "id": 3,
    "value": 25
  ,
  
    "id": 4,
    "value": 660
  ,
  
    "id": 5,
    "value": 132
  ,
  
    "id": 7,
    "value": 145
  
];
  
  List<Map<String, dynamic>> Currencies = [
  
    "id": 1,
    "name": "coin",
    "desc": "Dummytext.",
    "order": 101,
    "icon": "https://icon1.png"
  ,
  
    "id": 2,
    "name": "karma",
    "desc": "Dummytext.",
    "order": 102,
    "icon": "https://icon2.png"
  ,
  
    "id": 3,
    "name": "laurel",
    "desc": "Dummytext.",
    "order": 104,
    "icon": "https://icon3.png"
  ,
  
    "id": 4,
    "name": "diamonds",
    "desc": "Dummytext.",
    "order": 100,
    "icon": "https://icon4.png"
  ,
  
    "id": 5,
    "name": "tears",
    "desc": "Dummytext.",
    "order": 402,
    "icon": "https://icon5.png"
  ,
  
    "id": 6,
    "name": "shard",
    "desc": "Dummytext.",
    "order": 409,
    "icon": "https://icon6.png"
  ,
  
    "id": 7,
    "name": "relict",
    "desc": "Dummytext.",
    "order": 400,
    "icon": "https://icon7.png"
  ,
  
    "id": 9,
    "name": "seal",
    "desc": "Dummytext.",
    "order": 403,
    "icon": "https://icon9.png"
  ,
  
    "id": 10,
    "name": "silver",
    "desc": "Dummytext.",
    "order": 405,
    "icon": "https://icon10.png"
  
];
  
 List<Map<String, dynamic>> ExtendedWallet = [];
  Currencies.forEach((element)
      Wallet.forEach((e)
        if(e["id"]==element["id"])
          ExtendedWallet.add(
            getExtendedWallet(e["id"]
                              ,e["value"]
                              ,element["name"]
                              ,element["desc"],
                              element["order"],
                              element["icon"])
          );
        
      );
    
  );
  print(json.encode(ExtendedWallet).toString());


 Map<String, dynamic> getExtendedWallet(int id,int value,String name,String desc,int order,String icon)
  final Map<String, dynamic> data = new Map<String, dynamic>();
    data["id"] = id;
    data["value"] = value;
    data["name"] = name.toString();
    data["desc"] = desc.toString();
    data["order"] = order;
    data["icon"] = icon.toString();
    return data; 

【讨论】:

完美运行!你能解释一下这个功能吗?

以上是关于如何通过 Map 的特定键合并/加入两个 Map 列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何合并两个JAVA Map

合并两个地图并对相同键的值求和的最佳方法?

如何在 Scala 中以元组为键合并 Maps

在Java中合并两个嵌套映射

Flutter:如何合并两个对象并对同一个key的值求和?

Java 8 Stream根据某个相同的key合并两个Map List,其他key相同时优先保留其中一个List的值