【问题标题】:scala - Getting a read-only sublist view of a Listscala - 获取列表的只读子列表视图
【发布时间】:2010-12-01 21:27:31
【问题描述】:

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

List.slicefilter 一样是 O(n)。有没有比这更好的方法 - 我不需要像+- 等任何操作。只需applymapflatMap 等来提供子列表上的列表理解语法.

答案是写我自己的类,它的迭代器保持计数以知道终点在哪里?

【问题讨论】:

    标签: list scala iterator


    【解决方案1】:

    流呢? Stream 是 Scala 的懒惰方式。由于 Stream 的惰性,在这种情况下您需要的 Stream.take() 是 O(1)。唯一需要注意的是,如果您想在对 Stream 进行列表理解后返回 List,则需要将其转换回 List。 List.projection 为您提供了一个 Stream,它具有 List 的大部分操作。

    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)
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        好吧,在List 上,drop 的 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 可能是要走的路。

        【讨论】:

          猜你喜欢
          • 2013-08-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-27
          • 2023-03-18
          • 1970-01-01
          • 2012-09-04
          相关资源
          最近更新 更多