当想要合并两个map
Map<String, dynamic> a = {
'a': 1,
'c': {"c1": 1, "c2": 1},
};
Map<String, dynamic> b = {
'b': 1,
'c': {
"c1": 2,
},
};
可以这么写
Map<String, dynamic> c = {}..addAll(a)..addAll(b);
也可以用拓展运算符
Map<String, dynamic> c = {...a, ...b};
但是结果会有一些问题,深层次的属性会被直接覆盖掉
上边运算结果如下:
{a: 1, c: {c1: 2}, b: 1}
可能在某些场景并不符合你的预期,如期望以下结果,这时候我们用其他方法深度合并。
{a: 1, c: {c1: 2, c2: 1}, b: 1}
现成的类库如下(2323年12月14日):
belatuk_merge_map | Dart Package (pub.dev)
直接套用
import 'package:belatuk_merge_map/belatuk_merge_map.dart';
print(mergeMap([a, b]));
看下他的源码,很简单,就是递归检查,万变不离其宗。
Map<K, V> mergeMap<K, V>(Iterable<Map<K, V>> maps,
{bool recursive = true, bool acceptNull = false}) {
var result = <K, V>{};
for (var map in maps) {
_copyValues(map, result, recursive, acceptNull);
}
return result;
}
dynamic _copyValues<K, V>(
Map<K, V> from, Map<K, V?> to, bool recursive, bool acceptNull) {
for (var key in from.keys) {
if (from[key] is Map<K, V> && recursive) {
if (to[key] is! Map<K, V>) {
to[key] = <K, V>{} as V;
}
_copyValues(from[key] as Map, to[key] as Map, recursive, acceptNull);
} else {
if (from[key] != null || acceptNull) {
to[key] = from[key];
}
}
}
}
ps: 插件有个小问题,
调用mergeMap<String,dynamic> ,但是子属性map会转化为<dynamic,dynamic>;
将上方法第16行修改为下边,更符合我的需求。
_copyValues(from[key] as Map<K,V>, to[key] as Map<K,V>, recursive, acceptNull);