簡體   English   中英

在Scala中的一個for循環中有效地迭代一個Set,然后是另一個

[英]Efficiently iterate over one Set, and then another, in one for loop in Scala

我想使用單個循環迭代一個Set所有元素,然后迭代另一個Set所有元素。 (我不關心重復,因為我碰巧知道兩個Set是不相交的。)

我想在一個循環中完成它的原因是因為我有一些額外的代碼來測量進度,這需要它在一個循環中。

這通常不起作用,因為它可能會任意混合兩個Set

for(x <- firstSet ++ secondSet) {
   ...
}

這可行,但在內存中構建3個中間Seq ,因此在時間和空間使用方面效率太低:

for(x <- firstSet.toSeq ++ secondSet.toSeq) {
   ...
}
for(x <- firstSet.toIterator ++ secondSet.toIterator) {
   ...
}

這不構建任何中間數據結構,所以我認為這是最有效的方式。

如果你只是想要一個遍歷,並且你想要最大的性能,這是最好的方法,即使它是丑陋的:

val s1 = Set(1,2,3)
val s2 = Set(4,5,6)
val block : Int => Unit = x => { println(x) }
s1.foreach(block)
s2.foreach(block)

由於這非常難看,您可以為它定義一個類:

def traverse[T](a:Traversable[T], b:Traversable[T]) : Traversable[T] = 
  new Traversable[T] { 
    def foreach[U](f:T=>U) { a.foreach(f); b.foreach(f) } 
  }

然后像這樣使用它:

for(x<-traverse(s1, s2)) println(x)

但是,除非這對性能至關重要,否則Robin Green發布的解決方案會更好。 開銷是創建兩個迭代器並連接它們。 如果你有更深層次的嵌套數據結構,那么連接迭代器可能會非常昂貴。 例如,通過連接子樹的迭代器定義的樹迭代器將非常緩慢,而在每個子樹上調用foreach的樹遍歷將接近最優。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM