spebbe / dartz

Functional programming in Dart
MIT License
749 stars 60 forks source link

Add filter method to IMap #123

Open Iri-Hor opened 1 year ago

Iri-Hor commented 1 year ago

The IList class has the convenient filter method: filter(bool predicate(A a)) → IList

It would be handy to have the same mehtod in IMap

tcmhoang commented 1 year ago

You really don't need such method in IMap type. You can convert IMap to IList of Tuple and then use the filter method in IList like you always do.

I attached an example below for your convenience.

IMap.fromPairs(
      IMap.empty(StringOrder).pairs().filter((a) => true), // Put your predicate in here
      StringOrder,
    );
Iri-Hor commented 1 year ago

Thank you for the example! It helps solving my problem. But your solution creates an IList of tuples, then it creates the filtered IList and in the end it creates the resulting IMap. So two ILists are generated temporarily which you dont really need. That sounds really unefficient to me.

rich-j commented 1 year ago

We have a filter method implemented as an extension that uses a fold:

extension IMapX<K,V> on IMap<K,V> {
  IMap<K, V> filter(bool f(K k, V v)) =>
      this.foldLeftKV( IMap.empty(this.order), (a, K k, V v) => f(k,v) ? a.put(k, v) : a );
}

You can use it like:

final m = IMap.from(StringOrder, {"a":1,"b":2,"c":3});
final m2 = m.filter((k, v) => v != 2);
print("Map: $m  Map2: $m2");

Edit: @Iri-Hor your comment about temporary IList creation made me think about the efficiency of our folding filter extension. I feel that most of our filter operations remove a relatively small subset of items from the IMap so processing removals instead of puts might be more efficient.

extension IMapX<K,V> on IMap<K,V> {
  /// Alternative IMap filter implementation that initializes with the original IMap and removes filtered items
  IMap<K, V> filter(bool predicate(K k, V v)) =>
      this.foldLeftKV(this, (acc, K k, V v) => predicate(k,v) ? acc : acc.remove(k));
}

We have not benchmarked either of these implementations.