Search code examples
dartfunctional-programming

Dart: Obtaining a list from map's key-value


The following code works (blend1 is equal to blend2) , but it's quite ugly:

  1. The iteration should be over map entries, not over keys.
  2. It's pointless to catch a non-existing value when iterating over the keys.
  3. The expression colors[key] makes it slower than necessary.
void main() {
  final colors = {
    '1': 'red',
    '2': 'green',
    '3': 'blue'
  };

  final blend1 = colors.keys.map((key) => key + '-' + (colors[key] ?? ''));

  print(blend1);

  final blend2 = [
    '1-red',
    '2-green',
    '3-blue'
  ];

  print(blend2);
}

Can you suggest something nicer? I gather that I need to use colors.entries, but the result of colors.entries.map is a map, not a list.


Solution

  • You can use colors.entries.map.

    the result of colors.entries.map is a map, not a list.

    The result of that is neither a Map nor a List, .entries returns an Iterable<MapEntry<K, V>>. A MapEntry is just a class containing the key and value as properties.

    Then calling .map on an Iterable<MapEntry<K, V>> will give you an Iterable<T>, where T is whatever type you return in the callback function, in this case a String.

    void main() {
      final colors = {'1': 'red', '2': 'green', '3': 'blue'};
    
      final blend1 = colors.entries.map((entry) => '${entry.key}-${entry.value}');
    
      print(blend1);
    
      final blend2 = ['1-red', '2-green', '3-blue'];
    
      print(blend2);
    }
    

    If you want the result to be a List<String> instead of an Iterable<String> you can simply add a call to .toList().

    final blend1 = colors.entries.map((entry) => '${entry.key}-${entry.value}').toList();
    

    Or you can use a collection-for on a List literal.

    final blend1 = [for (final entry in colors.entries) '${entry.key}-${entry.value}'];