Scala: Creating a list of tuples from list elements sequentially
12,164
Solution 1
+=
is a method on theListBuffer
l2
that accepts repeated parameters. That means when you do something like this:scala> var l2 = scala.collection.mutable.ListBuffer[(Int, Int)]() l2: scala.collection.mutable.ListBuffer[(Int, Int)] = ListBuffer() scala> l2 += (1, 2) <console>:9: error: type mismatch; found : Int(1) required: (Int, Int) l2 += (1, 2)
.. The compiler thinks you are trying to add multiple Int
s to the ListBuffer
, when you are trying to add a tuple. You need an extra set of parentheses.
l1.zipWithIndex.slice(0,l1.length-1).foreach(x=> l2 += ((x._1,l1(x._2+1)) ))
You can use
sliding
, which will create a "sliding window" across the collection to return a list of lists of a specific group size, with a step size of one by default:scala> List(0, 3, 6, 12, 14, 15, 16, 17).sliding(2) .map { case List(a, b) => (a, b) }.toList res10: List[(Int, Int)] = List((0,3), (3,6), (6,12), (12,14), (14,15), (15,16), (16,17))
Solution 2
besides the sliding, you could slide like following:
val l1= List(0, 3, 6, 12, 14, 15, 16, 17)
val l2 = l1.take(l1.size - 1).zip(l1.tail)
updated
l1.zip(l1.tail) works.
Author by
rivu
Updated on June 08, 2022Comments
-
rivu almost 2 years
I am very new to Scala so this question may be very naive.
I have a list like this
List[Int] = List(0, 3, 6, 12, 14, 15, 16, 17)
. I am trying to create a list like this[(0,3),(3,6),(6,12)..]
and so on. So far this is what I have tried:val l1= List(0, 3, 6, 12, 14, 15, 16, 17) var l2=scala.collection.mutable.ListBuffer[(Int,Int)]() l1.zipWithIndex.slice(0,l1.length-1).foreach(x=>{val newval=(x._1,l1(x._2+1)); l2+=newval})
Two questions here:
- If I don't use
val newval
, i.e. try to dol1.zipWithIndex.slice(0,l1.length-1).foreach(x=>l2+=(x._1,l1(x._2+1)))
, the compiler says:<console>:10: error: type mismatch; found : Int required: (Int, Int) l1.zipWithIndex.slice(0,l1.length-1).foreach(x=>l2+=(x._1,l1(x._2+1)))
. Why is that? - What would a way to do it without the mutable listbuffer?
- If I don't use
-
Silly Freak over 8 years
size
may beO(n)
, so I'd preferdropRight
, and thendrop
for symmetry -
user1484819 over 8 yearssize is not O(n), but take is. I guess except head & tail, other methods on List are all O(n).
-
Michael Zajac over 8 years
l1.init
would be more idiomatic thanl1.take(l1.size - 1)
-
Silly Freak over 8 years@Paul you're right, I was mistaken about
dropRight
's implementation. I was basically thinking ofStream
's implementation. Anyway, isn't the wholetake
part redundant aszip
only takes commonly existing elements anyway? (even so, I agree that ensuring both lists have the same length is more readable) -
Alexander Aleksandrovič Klimov over 8 yearsYes,
l1.zip(l1.tail)
is all that's needed