2

I have some code where I need to add elements to a sequence while iterating over another one. Which way is the 'preferred' or rather the better way of doing that in scala and why?:

Way 1:

val builder = Seq.newBuilder[String]    
for(i <- iterator){
builder += i  //Everytime I want to add a new element    
}

Way 2:

val stringSeq = iterator.foldLeft(Seq[String]()){
case (acc, i) => i +: acc
}
Core_Dumped
  • 4,577
  • 11
  • 47
  • 71

3 Answers3

2

Why not use both, and be both functional and efficient?

iterator.foldLeft(Seq.newBuilder[String])(_ += _).result

Note that this code's behaviour is slightly different than that of your second solution: your solution reverse the iterator's order, mine preserves it. I don't know which is desired.

Also, just in case it didn't occur to you (sorry if I'm being obvious), any particular reason you're not using iterator.toSeq?

Nicolas Rinaudo
  • 6,068
  • 28
  • 41
1

I would say Way 2 is more idiomatic and feels more functional, as you do not create mutable state.

The Way 1 seems to be a bit more imperative, as it resembles for as it is used in the object oriented programming.

However Scala has both OOP elements and FP elements. I guess you should use a construct, which works better for you, due to for example performance reasons (however I don't think your example is the case, as appending to the head of Seq should be fast).

PS. your generator should be <- not < and it is foldLeft (capital L)

lpiepiora
  • 13,659
  • 1
  • 35
  • 47
1

There is a ++: method in Seq, so you can just do seq ++: iterator

And don't worry about performance, it's a basic API scala provide us and we should trust it.

Actually the current implementation is similar to your way 1.

cloud
  • 1,057
  • 7
  • 12