Scala:从列表元素顺序创建元组列表

7

我对Scala非常陌生,因此这个问题可能很幼稚。

我有一个列表,像这样 List[Int] = List(0, 3, 6, 12, 14, 15, 16, 17)。我想创建一个像这样的列表 [(0,3),(3,6),(6,12)..] 等等。到目前为止,这是我尝试过的:

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})

这里有两个问题:

  1. 如果我不使用 val newval,也就是尝试执行 l1.zipWithIndex.slice(0,l1.length-1).foreach(x=>l2+=(x._1,l1(x._2+1))),编译器会报错: <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)))。为什么会出现这种情况?
  2. 有没有一种方法可以不使用可变的listbuffer来实现它?
2个回答

10
  1. += is a method on the ListBuffer 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)
    

编译器认为您想要将多个Int添加到ListBuffer中,而实际上您是想要添加一个元组。您需要额外的一组括号。

 l1.zipWithIndex.slice(0,l1.length-1).foreach(x=> l2 += ((x._1,l1(x._2+1)) ))
  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))
    

3

除了滑动,您还可以按照以下方式进行滑动:

  val l1= List(0, 3, 6, 12, 14, 15, 16, 17)
  val l2 = l1.take(l1.size - 1).zip(l1.tail)

已更新

   l1.zip(l1.tail) works.

“size” 可能是 “O(n)”,所以我更喜欢使用 “dropRight”,然后对称地使用 “drop”。 - Silly Freak
大小不是 O(n),但获取是。我猜除了头和尾之外,列表上的其他方法都是 O(n)。 - user1484819
1
l1.initl1.take(l1.size - 1)更符合惯用语。 - Michael Zajac
@Paul 你说得对,我关于 dropRight 的实现是错误的。我基本上是在考虑 Stream 的实现。无论如何,整个 take 部分是否多余,因为 zip 只取共同存在的元素?(即使如此,我同意确保两个列表具有相同长度更易读) - Silly Freak
是的,只需要 l1.zip(l1.tail) - The Archetypal Paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接