Home > Mobile >  How to `map` an `Iterable` partially in Dart?
How to `map` an `Iterable` partially in Dart?

Time:01-04

Assuming I have a List as below:

final numbers = [1, 0, -1, 1, -3, 0];

I'd like to generate another list where 1 results in true and 0 results in false and skip the others. So, in other words, I'd like a method like map where I can also skip some elements. In terms of test, it would assert to:

expect(newList, equals([true, false, true, false]));

In this result, I'd like to skip -1 and -3 in the list.

How can I achieve this?


Environment

  • Dart 2.18.5

CodePudding user response:

Use the .where() method to get a new iterable with only the elements satisfying a predicate, then use .map() to apply the transformation on the result.

final numbers = [1, 0, -1, 1, -3, 0];
final result = numbers.where((n) => n == 1 || n == 0).map((n) => n == 1);
print(result);

\\ (true, false, true, false)

CodePudding user response:

Ariel's answer gave me a better idea. In the example of the question, what we'd like to filter out are two values, which are 1 and 0. The real problem I'm dealing with right now is more complicated than this one, it has a wide range of lookup list. I haven't specifically asked "What is a more programmatic way to do this?" or "What if the lookup list has more values?".

So, if the values I'm looking for are more than these two values, a List of lookup values and contains method would be better for my case.

final numbers = [1, 0, -1, 1, -3, 0];
final lookup = {1, 0};
final result = numbers.where((n) => lookup.contains(n)).map((n) => n == 1 ? true : false).toList();
print(result);

This has some drawbacks though, some of which that come to my mind are:

  • Performance is definitely worse than Ariel's answer. My solution uses contains, which will perform look-ups in lookup rather than a simple byte-comparison with n == 1. So, it isn't great with large lists.
  • hashCode must be overriden for non-primitives. It is easy to compare int with an int in this simple example, but if you have an instance, you need to override hashCode, otherwise Dart will compare the memory addresses rather than values.
  • Using another collection type for lookup other than Set might also have performance impact because Set is inherently O(1) while the others might depend on their standard library implementation, but it's safe to assume they're going to be worse than Set. (See Ariel's comment).

BTW, lookup does not have to be a Set. I've done it Set because lookup contains distinct values and the order is not important.

  •  Tags:  
  • dart
  • Related