Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: "map" vs "foreach" - is there any reason to use "foreach" in practice?

In Scala collections, if one wants to iterate over a collection (without returning results, i.e. doing a side effect on every element of collection), it can be done either with

final def foreach(f: (A) ⇒ Unit): Unit

or

final def map[B](f: (A) ⇒ B): SomeCollectionClass[B]

With the exception of possible lazy mapping(*), from an end-user perspective, I see zero differences in these invocations:

myCollection.foreach { element =>
  doStuffWithElement(element);
}

myCollection.map { element =>
  doStuffWithElement(element);
}

given that I can just ignore what map outputs. I can't think of any specific reason why two different methods should exist & be used, when map seems to include all the functionality of foreach, and, in fact, I would be pretty much impressed if an intelligent compiler & VM won't optimize out that collection object creation given that it's not assigned to anything, or read, or used anywhere.

So, the question is - am I right - and there are no reasons to call foreach anywhere in one's code?

Notes:

(*) The lazy mapping concept, as throughly illustrated in this question, might change things a bit and justify usage of foreach, but as far as I can see, one specifically needs to stumble upon a LazyMap, normal

(**) If one's not using a collection, but writing one, then one would quickly stumble upon the fact that for comprehension syntax syntax is in fact a syntax sugar that generates "foreach" call, i.e. these two lines generate fully equivalent code:

for (element <- myCollection) { doStuffWithElement(element); }
myCollection.foreach { element => doStuffWithElement(element); }

So if one cares about other people using that collection class with for syntax, one might still want to implement foreach method.

like image 223
GreyCat Avatar asked Sep 10 '14 00:09

GreyCat


People also ask

Should I use forEach or map?

The main difference between map and forEach is that the map method returns a new array by applying the callback function on each element of an array, while the forEach method doesn't return anything. You can use the forEach method to mutate the source array, but this isn't really the way it's meant to be used.

Which is faster forEach or map?

Final Thoughts. You can use both map() and forEach() interchangeably. The biggest difference is that forEach() allows the mutation of the original array, while map() returns a new array of the same size. map() is also faster.

What is the difference between map () and forEach () iterations methods?

Differences between forEach() and map() methods: The forEach() method returns “undefined“. The map() method returns the newly created array according to the provided callback function. The forEach() method doesn't return anything hence the method chaining technique cannot be applied here.

Should I use forEach?

forEach() is great you need to execute a function for each individual element in an array. Good practice is that you should use . forEach() when you can't use other array methods to accomplish your goal.


1 Answers

I can think of a couple motivations:

  1. When the foreach is the last line of a method that is of type Unit your compiler will not give an warning but will with map (and you need -Ywarn-value-discard on). Sometimes you get warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses using map but wouldn't with foreach.
  2. General readability - a reader can know that your mutating some state without returning something at a glance, but greater cognitive resources would be required to understand the same operation if map was used
  3. Further to 1. you also can have type checking when passing named functions around, then into map and foreach
  4. Using foreach won't build a new list, so will be more efficient (thanks @Vishnu)
like image 59
samthebest Avatar answered Sep 20 '22 11:09

samthebest