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
相关产品推荐
相关产品推荐

