Open Iri-Hor opened 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,
);
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.
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.
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