Anders
Anders

Reputation: 1377

How can I filter a map / access the entries

The Map interface doesn't seem to provide access to the entries as an iterable, nor does it expose a where method to filter entries. Am I missing something? Is there a simple workaround?

e.g.

Map map;
final filteredMap = map.where((k, v) => k.startsWith("foo"));

Upvotes: 40

Views: 32421

Answers (6)

Gábor
Gábor

Reputation: 10224

You can still use the simple where() function:

final filtered = Map.fromEntries(original.entries.where((item) => ...));

Upvotes: 1

odiggity
odiggity

Reputation: 1566

You can just create an extension function and then use it anywhere in your code.

Put this in any file (I called mine MapUtils.dart)

extension MapUtils<K, V> on Map<K, V> {

  Map<K, V> where(bool Function(K, V) condition) {
    Map<K, V> result = {};
    this.entries.forEach((element) {
      if (condition(element.key, element.value)) {
        result[element.key] = element.value;
      }
    });
    return result;
  }
}

and then use it like so:

Map<String, int> peopleHeight = {"Bob":170, "Alice":130};
Map<String, int> shortPeople = peopleHeight.where((name, height) => height < 140);

Upvotes: 1

atreeon
atreeon

Reputation: 24097

I use dartx and it's filter method

  var myMap = {
    "a": [1, 2, 3],
    "b": [4, 5, 6],
    "c": [7, 8, 9],
  };

  var result = myMap.filter((entry) => entry.key != "a");

Upvotes: 2

Update: with control flow collection statements you can also do this:

final filteredMap = {
  for (final key in map.keys)
    if (!key.startsWith('foo')) key: map[key]
};

Original answer: Dart 2.0.0 added removeWhere which can be used to filter Map entities. Given your example, you could apply this as:

Map map;
final filteredMap = Map.from(map)..removeWhere((k, v) => !k.startsWith("foo"));

It's not the where method you asked for, but filtering Map entities is certainly doable this way.

Upvotes: 54

Jannie Theunissen
Jannie Theunissen

Reputation: 30164

Since Dart 2.0 Maps have an entries getter that returns an Iterable<MapEntry<K, V>> so you can do:

MapEntry theOne = map.entries.firstWhere((entry) {
        return entry.key.startsWith('foo');
      }, orElse: () => MapEntry(null, null));

Upvotes: 7

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657338

You can use

library x;

void main(List<String> args) {
  Map map = {'key1': 'aölsjfd', 'key2': 'oiweuwrow', 'key11': 'oipoip', 'key13': 'werwr'};

  final filteredMap = new Map.fromIterable(
      map.keys.where((k) => k.startsWith('key1')), key: (k) => k, value: (k) => map[k]);

  filteredMap.forEach((k, v) => print('key: $k, value: $v'));
}

Upvotes: 6

Related Questions