Skip to content

Instantly share code, notes, and snippets.

@andreacioni
Created April 3, 2022 16:51
Show Gist options
  • Save andreacioni/3788ed96a0c705a4ed923aafcf6aa8ac to your computer and use it in GitHub Desktop.
Save andreacioni/3788ed96a0c705a4ed923aafcf6aa8ac to your computer and use it in GitHub Desktop.
DeepMerge Dart
emptyTarget(val) {
return val is List ? [] : {};
}
dynamic cloneUnlessOtherwiseSpecified(value) {
print('$value');
return isMergeableObject(value)
? deepmerge(emptyTarget(value), value)
: value;
}
List defaultArrayMerge(List target, List source) {
return [...target, ...source]
.map((element) => cloneUnlessOtherwiseSpecified(element))
.toList();
}
bool propertyIsOnObject(Map<dynamic, dynamic> object, dynamic property) {
return object.containsKey(property);
}
// Protects from prototype poisoning and unexpected merging up the prototype chain.
bool propertyIsUnsafe(target, key) {
return propertyIsOnObject(target, key); // Properties are safe to merge if they don't exist in the target yet
}
bool isMergeableObject(obj) {
return obj != null && (obj is List || obj is Map);
}
Map<dynamic, dynamic> mergeObject(
Map<dynamic, dynamic> target, Map<dynamic, dynamic> source) {
Map<dynamic, dynamic> destination = {};
if (isMergeableObject(target)) {
for (final key in target.keys) {
destination[key] = cloneUnlessOtherwiseSpecified(target[key]);
}
}
for (final key in source.keys) {
if (propertyIsUnsafe(target, key)) {
continue;
}
print('T: $target S: $source');
if (propertyIsOnObject(target, key) && isMergeableObject(source[key])) {
destination[key] = deepmerge(target[key], source[key]);
} else {
destination[key] = cloneUnlessOtherwiseSpecified(source[key]);
}
}
return destination;
}
deepmerge(dynamic target, dynamic source) {
final isList = target is List && source is List;
final isMap = target is Map && source is Map;
if (isMap) {
print(target);
return mergeObject(target, source);
} else if (isList) {
print('lizf $target $source');
return defaultArrayMerge(target, source);
} else {
return cloneUnlessOtherwiseSpecified(source);
}
}
void main() {
print('ciao');
final Map<String, dynamic> a = {
'zio': 1,
'rotolo': 2,
'pino': [4]
};
final Map<String, dynamic> b = {
'zio': 'pane',
'giovannni': 'pallini',
'pino': [3]
};
final r = deepmerge(a, b);
print('result: $r');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment