5

Is there an idiomatic way to apply a function to all items in a list ?

For example, in Python, say we wish to capitalize all strings in a list, we can use a loop :

regimentNames = ['Night Riflemen', 'Jungle Scouts', 'The Dragoons', 'Midnight Revengence', 'Wily Warriors']
# create a variable for the for loop results
regimentNamesCapitalized_f = []

# for every item in regimentNames
for i in regimentNames:
    # capitalize the item and add it to regimentNamesCapitalized_f
    regimentNamesCapitalized_f.append(i.upper())

But a more concise way is:

capitalizer = lambda x: x.upper()
regimentNamesCapitalized_m = list(map(capitalizer, regimentNames)); regimentNamesCapitalized_m

What is an equivalent way to call a function on all items in a list in Dart ?

Rahul Iyer
  • 19,924
  • 21
  • 96
  • 190

2 Answers2

7

If you want to apply a function to all items in a List (or Iterable) and collect the results, Dart provides an Iterable.map function that is equivalent to Python's map:

// Dart
regimentNamesCapitalized_m = regimentNames.map((x) => x.toUpperCase()).toList();

Python also provides list comprehensions, which usually are considered more Pythonic and often are preferred to the functional approach:

# Python
regimentNamesCapitalized_m = [x.upper() for x in regimentNames]

Dart's equivalent of Python's list comprehensions is collection-for:

// Dart
regimentNamesCapitalized_m = [for (var x in regimentNames) x.toUpperCase()];

If you're calling a function for its side-effect and don't care about its return value, you could use Iterable.forEach instead of Iterable.map. In such cases, however, I personally prefer explicit loops:

  • I think they're more readable by virtue of being more common.
  • They're more flexible. You can use break or continue to control iteration.
  • They might be more efficient. .forEach involves an extra function call per iteration to invoke the supplied callback.
jamesdlin
  • 81,374
  • 13
  • 159
  • 204
3

The answer seems to be to use anonymous functions, or pass a function to a lists forEach method.

Passing a function:

void capitalise(var string) {
  var foo = string.toUpperCase();
  print(foo);
}

var list = ['apples', 'bananas', 'oranges'];
list.forEach(capitalise);

Using an anonymous function:

list.forEach((item){
  print(item.toUpperCase());
});

If the function is going to be used only in one place, I think its better to use the anonymous function, as it is easy to read what is happening in the list.

If the function is going to be used in multiple places, then its better to pass the function instead of using an anonymous function.

Rahul Iyer
  • 19,924
  • 21
  • 96
  • 190
  • It's weird that your Python example used `map` but you don't use `List.map` your Dart code, which is a direct analogue. Your examples here also aren't the same as the Python versions since the Python ones produced *lists*, but here you're just printing each element. – jamesdlin Aug 13 '20 at 07:12
  • @jamesdlin The point of my question was just discussing efficient ways to pass a function to all items in a list. Doesn't matter to me whether it actually capitalises it or prints it. – Rahul Iyer Aug 13 '20 at 07:14
  • Your question asks for "an equivalent way", so IMO you should provide equivalent code, especially since it's trivial to do so. – jamesdlin Aug 13 '20 at 07:18