我想要List
,Seq
,甚至是Iterable
,它是List的一部分的只读视图,在我的特定情况下,视图将始终从第一个元素开始。
List.slice
,与filter
一样是O(n)。无论如何还是比这更好 - 我不需要+
,-
等任何操作。只需apply
,map
,flatMap
等在子列表上提供列表理解语法。
是编写我自己的类的答案,其迭代器会计算知道结束的位置吗?
答案 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)
嗯,drop
上List
的O(n)不能好过。至于其余的:
def constantSlice[T](l: List[T], start: Int, end: Int): Iterator[T] =
l.drop(start).elements.take(end - start)
elements
和take
(在迭代器上)都是O(1)。
当然,Iterator
不是Iterable
,因为它不可重复使用。在Scala 2.8上,优先选择返回Iterable
而不是Iterator
。如果您需要在Scala 2.7上重用,那么Stream
可能就是您的选择。