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?

1

5 Answers

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.

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.

  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.

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 
2

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.