Adam Smaka
Adam Smaka

Reputation: 6393

Dart - How to convert nested Map<dynamic, dynamic> to Map<String, dynamic>

I know how to convert Map<dynamic, dynamic> to Map<String, dynamic> using Map.from() method. But what if I have unspecified number of nested Maps inside? How to convert all potential children as well from Map<dynamic, dynamic> to Map<String, dynamic>?

Upvotes: 2

Views: 2923

Answers (4)

bigzhu
bigzhu

Reputation: 91

Map<String, dynamic> convertMap(Map<dynamic, dynamic> map) {
  map.forEach((key, value) {
    if (value is Map) {
      // logger.d("key: $key ${value.runtimeType}");
      // it's a map, process it
      map[key] = convertMap(value);
      // logger.d("key: $key ${value.runtimeType}");
    }
  });
  // use .from to ensure the keys are Strings
  return Map<String, dynamic>.from(map);
  // more explicit alternative way:
  // return Map.fromEntries(map.entries.map((entry) => MapEntry(entry.key.toString(), entry.value)));
}

Upvotes: 0

Choon Yap Pui
Choon Yap Pui

Reputation: 11

Same answer but with additional condition for List

/// recursively convert the map tp Map<String,dynamic>
Map<String, dynamic> convertMap(Map<dynamic, dynamic> map) {
  for (var key in map.keys) {
    if (map[key] is Map) {
      map[key] = convertMap(map[key]);
    } else if (map[key] is List) {
      map[key] = map[key].map((e) {
        if (e is Map) {
          return convertMap(e);
        }
        return e;
      }).toList();
    }
  }
  return Map<String, dynamic>.from(map);
}

Upvotes: 1

Moacir Schmidt
Moacir Schmidt

Reputation: 935

Same answer as fravolt's but I was unable do put code in comments:

Map.forEach do not treats value by reference. You may change to:

// recursively convert the map
Map<String, dynamic> convertMap(Map<dynamic, dynamic> map) {
    for (var key in map.keys) {
      if (map[key] is Map) {
        map[key] = convertMap(map[key]);
      }
    }  // use .from to ensure the keys are Strings
  return Map<String, dynamic>.from(map);
  // more explicit alternative way:
  // return Map.fromEntries(map.entries.map((entry) => MapEntry(entry.key.toString(), entry.value)));
}

Upvotes: 2

fravolt
fravolt

Reputation: 3001

You could use a recursive approach to this problem, where all map values of type Map are recursively converted as well.

// recursively convert the map
Map<String, dynamic> convertMap(Map<dynamic, dynamic> map) {
  map.forEach((key, value) {
    if (value is Map) {
      // it's a map, process it
      value = convertMap(value);
    }
  });
  // use .from to ensure the keys are Strings
  return Map<String, dynamic>.from(map);
  // more explicit alternative way:
  // return Map.fromEntries(map.entries.map((entry) => MapEntry(entry.key.toString(), entry.value)));
}

// example nested map with dynamic values
Map<dynamic, dynamic> nestedMap = {
  'first': 'value',
  'second': {
    'foo': 'bar',
    'yes': 'ok',
    'map': {'some': 'value'},
  }
};

// convert the example map
Map<String, dynamic> result = convertMap(nestedMap);
print(result);

Upvotes: 0

Related Questions