5

i tried two ways for making a list out of something

var response = List[RS_TxnNested]
consumertxnlist.foreach(txData => {
  response = RS_TxnNested(blabla) +: response
})

where consumertxnlist is a Seq[something] .

Another way is

var response = consumerTxnList._2.map(txData => RS_TxnNested(blabla))

Can someone help me in clarifying which one is better and why?

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
legacy_shield
  • 163
  • 1
  • 5
  • I think you will get your answer here http://stackoverflow.com/questions/17080186/difference-between-map-and-foreach-method-in-scala – Sandeep Purohit May 18 '17 at 08:39

5 Answers5

12

As you've noticed already, the map function in the Seq trait returns a value. Its signature in fact is

def map[B](f: (A) ⇒ B): Seq[B]

It is designed to apply a function to every element of a collection extending the Seq trait and return a new collection.

On the other hand, foreach, in the same trait, has the following signature:

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

This means that it's designed to execute functions with side-effects.

In your example, you're treating the operation of assigning the value to "response" as a side effect. If you're actual goal is to return a value (like it seems you want to do), then use map.

DeusEx
  • 147
  • 1
  • 7
2

The second version is more explicit in what it does.

map conveys a meaning of transforming something, which is exactly what you're doing.

foreach instead performs an operation on something outside its scope, which is not as clear.

In other words, when I read foreach I have to look at the whole scope, because I know you'll be performing a side effect (since foreach returns Unit)

When I read map I can confidently assume the only expression involved is the one I'm currently looking at.

map lowers the burden on the reader, and makes the code easier to reason about.

Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
2
  1. Using the foreach and the prepending of the elements will yield a List with elements in reversed order.

  2. When using foreach you have to define response as a var, while using map you can define response as a val.

I would suggest to use map since it better resembles your intent.

wwkudu
  • 2,778
  • 3
  • 28
  • 41
senjin.hajrulahovic
  • 2,961
  • 2
  • 17
  • 32
1

Using foreach returns Unit (nothing) which can be used if you're doing side effects or something like that.

If you want to return data then you should use things like map, flatMap, fold and others.

scala> val l: List[String] = List("a", "b", "c")
l: List[String] = List(a, b, c)

scala> l.map(e => e.toUpperCase(java.util.Locale.ROOT))
res0: List[String] = List(A, B, C)

scala> l.foreach(e => println(e))
a
b
c
jan0sch
  • 62
  • 6
  • Thanks for the answer...But in my case i am confused..I am making a list inside foreach loop using the element of Seq but on the other hand i am not making any changes on the elements itself(not making any operations on elements of Seq) – legacy_shield May 18 '17 at 08:46
  • Why do you re-create a list? If you just need another list type you could try the `.to...` operators (toList, toSeq, to[T]). – jan0sch May 18 '17 at 08:48
1

If you want to return the object from your loop operation , I think you should avoid forEach . Rather go for foldLeft or some other kind of fold operation. As far as your question is concerned , once again if you are returning response then you should go with map else forEach should work fine.

ankur jha
  • 11
  • 1