Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add filter method to IMap #123

Open
Iri-Hor opened this issue Mar 27, 2023 · 3 comments
Open

Add filter method to IMap #123

Iri-Hor opened this issue Mar 27, 2023 · 3 comments

Comments

@Iri-Hor
Copy link

Iri-Hor commented Mar 27, 2023

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
Copy link

tcmhoang commented Apr 15, 2023

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
Copy link
Author

Iri-Hor commented Apr 19, 2023

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
Copy link

rich-j commented Apr 19, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants