I would like to know how to get the value of a nested dictionary or to update value of the nested dictionary using keypath in dart (Flutter).
4 Answers
Simple recursive implementation:
/// Get the value from the [map] using passed [path] of keys
/// in the format key1.key2.key3... etc.
/// Returns null if [path] do not exists.
Object? getFromPath(Object? map, String path) {
if (map is! Map<String, dynamic>) return null;
int index = path.indexOf('.');
if (index < 0) return map[path];
return getFromPath(map[path.substring(0, index)], path.substring(index + 1));
}
Example:
final Map<String, Object> map = {
'a1': {
'b1': {
'c1': {
'd1': 'hello',
'd2': 'world'
}
}
}
};
print(getFromPath(map, 'a1.b1.c1.d1')); //hello
print(getFromPath(map, 'a1.b1.c1.d2')); //world
Comments
i think no need for recursion since this is a for loop
this should be better performance
dynamic getValueForKeyPath({@required Map<String, dynamic> json, @required String path}) {
final List<String> pathList = path.split('.');
Map<String, dynamic> _map = json;
for (String element in pathList) {
if (_map[element] is Map<String, dynamic>) {
_map = _map[element];
} else {
return _map[element];
}
}
Comments
If you have a dictionary like this:
{
"example": {
"a": "valA",
"b": "valB",
"c": "valC",
}
}
You can create a class that parses this object:
class Example {
String a;
String b;
String c;
Example({
this.a,
this.b,
this.c,
});
factory Example.parseJSON(Map<String, String> json) {
return Example(
a: json['example']['a'],
b: json['example']['b'],
c: json['example']['c'],
);
}
}
4 Comments
Pathak Ayush
any other method to access like json['example.a']
Aleksandar
That is not a syntax recognised by Dart. There are specific libraries that support this nested syntax, but that's a dependency on the project, and there are different use-cases for each.
Pathak Ayush
can you tell me about those dependency ?
Aleksandar
There is a detailed description about 2 topics and libraries that can use notation you mentioned: 1. when doing app localization pub.dev/packages/easy_localization 2. when doing json parsing flutter.dev/docs/development/data-and-backend/json
You can do it like this:
dynamic getValueForKeyPath(
{required Map<String, dynamic> json, required String path}) {
final List<String> pathList = path.split('.');
final List<String> remainingPath = path.split('.');
for (String element in pathList) {
remainingPath.remove(element);
if (json[element] is Map<String, dynamic>) {
return getValueForKeyPath(
json: json[element], path: remainingPath.join('.'));
} else {
return json[element];
}
}
And given your map look like:
Map<String, dynamic> data = { "data": { "nestedData": { "nestedValue": { "value": "10" }, "targetValue": "20" }}};
You can get the nested 'value' by calling:
print('Result ${getValueForKeyPath(json: data, path: 'data.nestedData.nestedValue.value')}');
Which will print 'Result 10'