Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala for loop over two lists simultaneously

I have a List[Message] and a List[Author] which have the same number of items, and should be ordered so that at each index, the Message is from the Author.

I also have class that we'll call here SmartMessage, with a constructor taking 2 arguments: a Message and the corresponding Author.

What I want to do, is to create a List[SmartMessage], combining the data of the 2 simple lists.

Extra question: does List preserve insertion order in Scala? Just to make sure I create List[Message] and a List[Author] with same ordering.

like image 425
Blackbird Avatar asked Jun 19 '13 19:06

Blackbird


1 Answers

You could use zip:

val ms: List[Message] = ??? val as: List[Author] = ???  var sms = for ( (m, a) <- (ms zip as)) yield new SmartMessage(m, a) 

If you don't like for-comprehensions you could use map:

var sms = (ms zip as).map{ case (m, a) => new SmartMessage(m, a)} 

Method zip creates collection of pairs. In this case List[(Message, Author)].

You could also use zipped method on Tuple2 (and on Tuple3):

var sms = (ms, as).zipped.map{ (m, a) => new SmartMessage(m, a)} 

As you can see you don't need pattern matching in map in this case.

Extra

List is Seq and Seq preserves order. See scala collections overview.

There are 3 main branches of collections: Seq, Set and Map.

  • Seq preserves order of elements.
  • Set contains no duplicate elements.
  • Map contains mappings from keys to values.

List in scala is linked list, so you should prepend elements to it, not append. See Performance Characteristics of scala collections.

like image 142
senia Avatar answered Oct 01 '22 23:10

senia