如何在不计算底层迭代器的情况下链接 Iterable
How to chain Iterable without computing underlying iterators
如果我有两个迭代器,我可以只写 iter1 ++ iter2
并且在需要它们之前不会计算迭代器。有没有办法以相同的方式链接 Iterable
个实例?
我尝试使用 iterable1 ++ iterable2
但它会导致立即计算嵌套值,就像将它们添加到某些结构中一样。是否可以避免这种额外的计算并创建额外的数据结构?
没有。 Iterable
只是一个接口,可以由任何可以迭代的东西来实现。所以当你有一个 Iterable[Int]
可以是惰性集合或严格集合时,没有办法知道。
scala> val iterable1: Iterable[Int] = List(1,2,3)
iterable1: Iterable[Int] = List(1, 2, 3)
scala> iterable1 ++ iterable1
res2: Iterable[Int] = List(1, 2, 3, 1, 2, 3)
scala> val iterable2: Iterable[Int] = List(1,2,3).view
iterable2: Iterable[Int] = SeqView(...)
scala> iterable2 ++ iterable2
res3: Iterable[Int] = SeqViewA(...)
您可以编写一个简单的 chain-iterable,它是 Iterable 的惰性串联:
case class Chain[A](iter: Iterable[A]*) extends Iterable[A]{
def iterator: Iterator[A] = iter.map(_.iterator).foldLeft(Iterator.empty: Iterator[A])(_++_)
}
Chain(List(1,2,3), 10 to 15, Vector(42,13))
如果我有两个迭代器,我可以只写 iter1 ++ iter2
并且在需要它们之前不会计算迭代器。有没有办法以相同的方式链接 Iterable
个实例?
我尝试使用 iterable1 ++ iterable2
但它会导致立即计算嵌套值,就像将它们添加到某些结构中一样。是否可以避免这种额外的计算并创建额外的数据结构?
没有。 Iterable
只是一个接口,可以由任何可以迭代的东西来实现。所以当你有一个 Iterable[Int]
可以是惰性集合或严格集合时,没有办法知道。
scala> val iterable1: Iterable[Int] = List(1,2,3)
iterable1: Iterable[Int] = List(1, 2, 3)
scala> iterable1 ++ iterable1
res2: Iterable[Int] = List(1, 2, 3, 1, 2, 3)
scala> val iterable2: Iterable[Int] = List(1,2,3).view
iterable2: Iterable[Int] = SeqView(...)
scala> iterable2 ++ iterable2
res3: Iterable[Int] = SeqViewA(...)
您可以编写一个简单的 chain-iterable,它是 Iterable 的惰性串联:
case class Chain[A](iter: Iterable[A]*) extends Iterable[A]{
def iterator: Iterator[A] = iter.map(_.iterator).foldLeft(Iterator.empty: Iterator[A])(_++_)
}
Chain(List(1,2,3), 10 to 15, Vector(42,13))