给定列表中每个第n项的列表

Mic*_*ael 12 scala scala-collections

这是我在Scala中解决的一个简单练习:给定一个列表l返回一个新列表,其中包含每个n-th元素l.如果n > l.size返回一个空列表.

def skip(l: List[Int], n: Int) = 
  Range(1, l.size/n + 1).map(i => l.take(i * n).last).toList
Run Code Online (Sandbox Code Playgroud)

我的解决方案(见上文)似乎工作,但我正在寻找smth.简单.你会如何简化它?

The*_*aul 18

有点简单:

scala> val l = (1 to 10).toList
l: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

// n == 3

scala> l.drop(2).grouped(3).map(_.head).toList
res0: List[Int] = List(3, 6, 9)

// n > l.length

scala> l.drop(11).grouped(12).map(_.head).toList
res1: List[Int] = List()
Run Code Online (Sandbox Code Playgroud)

(toList只是为了强制评估iteratot)

使用无限列表:

Stream.from(1).drop(2).grouped(3).map(_.head).take(4).toList
res2: List[Int] = List(3, 6, 9, 12)
Run Code Online (Sandbox Code Playgroud)


Mar*_*rth 8

scala> def skip[A](l:List[A], n:Int) = 
         l.zipWithIndex.collect {case (e,i) if ((i+1) % n) == 0 => e} // (i+1) because zipWithIndex is 0-based
skip: [A](l: List[A], n: Int)List[A]

scala> val l = (1 to 10).toList
l: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> skip(l,3)
res2: List[Int] = List(3, 6, 9)

scala> skip(l,11)
res3: List[Int] = List()
Run Code Online (Sandbox Code Playgroud)

  • 那么它看起来简单的我(主要是从'zipWithIndex`使得它明确你正在做与指数东西的事实),但主要的好处是,你不叫`l.take(I).last` (它等同于(并且慢于)l(i)`),因为以这种方式获得元素是带有列表的O(n). (2认同)