scala - 获取List的只读子列表视图

时间:2009-09-28 02:50:03

标签: list scala iterator

我想要ListSeq,甚至是Iterable,它是List的一部分的只读视图,在我的特定情况下,视图将始终从第一个元素开始。

List.slice,与filter一样是O(n)。无论如何还是比这更好 - 我不需要+-等任何操作。只需applymapflatMap等在子列表上提供列表理解语法。

是编写我自己的类的答案,其迭代器会计算知道结束的位置吗?

3 个答案:

答案 0 :(得分:6)

Stream怎么样? Stream是Scala的懒惰方式。由于Stream的懒惰,Stream.take(),在这种情况下你需要的是O(1)。唯一需要注意的是,如果您想在Stream上执行列表解析后返回List,则需要将其转换回List。 List.projection为您提供了一个包含List的大部分操作的Stream。

scala> val l = List(1, 2, 3, 4, 5)
l: List[Int] = List(1, 2, 3, 4, 5)

scala> val s = l.projection.take(3)
s: Stream[Int] = Stream(1, ?)

scala> s.map(_ * 2).toList
res0: List[Int] = List(2, 4, 6)

scala> (for (i <- s) yield i * 2).toList
res1: List[Int] = List(2, 4, 6)

答案 1 :(得分:5)

List.slice和List.filter都返回Lists - 根据定义,它们是不可变的。+和 - 方法返回不同的List,它们不会更改原始List。而且,很难比O(N)做得更好。 List不是随机访问,而是链表。因此,想象一下,如果您想要的子列表是List的最后一个元素。访问该元素的唯一方法是遍历整个List。

答案 2 :(得分:4)

嗯,dropList的O(n)不能好过。至于其余的:

def constantSlice[T](l: List[T], start: Int, end: Int): Iterator[T] =
  l.drop(start).elements.take(end - start)

elementstake(在迭代器上)都是O(1)。

当然,Iterator不是Iterable,因为它不可重复使用。在Scala 2.8上,优先选择返回Iterable而不是Iterator。如果您需要在Scala 2.7上重用,那么Stream可能就是您的选择。