You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart 向嵌套Map添加数据且不覆盖原有值的问题咨询

Dart多层嵌套Map非覆盖式自动创建上层节点赋值方案

核心思路

逐层遍历嵌套层级的key,每一层判断当前节点是否为Map类型,不存在就初始化空Map,最后一层再赋值,全程不会修改已存在的其他节点数据,也避免了直接访问不存在节点的报错问题。

方案1:封装通用嵌套赋值函数

void deepPut(Map<dynamic, dynamic> rootMap, List<dynamic> nestedKeys, dynamic targetValue) {
  final lastKey = nestedKeys.removeLast();
  dynamic currentNode = rootMap;
  // 遍历除最后一个key外的所有上层key,自动创建不存在的节点
  for (final key in nestedKeys) {
    if (currentNode[key] is! Map) {
      currentNode[key] = <dynamic, dynamic>{};
    }
    currentNode = currentNode[key];
  }
  // 最后一层赋值,不会影响同层级其他已存在的值
  currentNode[lastKey] = targetValue;
}

调用示例

// 要赋值 Program['day0']['area0']['exercise0'] = 'success'
deepPut(Program, ['day0', 'area0', 'exercise0'], 'success');

如果day0、area0任意上层节点不存在会自动初始化,已存在则直接修改exercise0的值,同层级其他已有的节点数据不会被覆盖。

方案2:扩展方法简化调用

通过Dart扩展能力把方法挂载到Map类型上,调用更直观:

extension NestedMapExtension on Map {
  void deepPut(List<dynamic> nestedKeys, dynamic targetValue) {
    final lastKey = nestedKeys.removeLast();
    dynamic currentNode = this;
    for (final key in nestedKeys) {
      if (currentNode[key] is! Map) {
        currentNode[key] = <dynamic, dynamic>{};
      }
      currentNode = currentNode[key];
    }
    currentNode[lastKey] = targetValue;
  }
}

调用示例

Program.deepPut(['day${dayIndex}', 'area0', 'exercise0'], {'exercise': Chest.exercises[0]});

批量写入上层节点的注意事项

之前的addAll会覆盖整层数据,是因为你直接替换了上层key对应的整个Map,要避免覆盖可以先获取已有的上层节点再合并:

// 先确保day节点存在,不存在就初始化
Program.putIfAbsent('day${dayIndex}', () => <String, dynamic>{});
final dayNode = Program['day${dayIndex}'] as Map;
// 给day节点合并新增area,已存在的area不会被覆盖
dayNode.addAll({
  "area0": { 
    'area': Chest, 
    'exercise0': {'exercise': Chest.exercises[0]}, 
  },
  "area1": { 
    'area': FrontArm, 
    'exercise0': {'exercise': FrontArm.exercises[0]}, 
  }
});

内容的提问来源于stack exchange,提问作者Oğuz Kaan Demir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 06:45:04