因爲所有你檢查的存在,你可以組成2種的用途exists
:
(0 until x).exists(i => (i + 1 until x).exists(fn(i, _)))
更一般地,如果您關心的不僅僅是確定一個特定的元素存在更多,您可以將您的理解轉化爲一系列Streams
,Iterators
,或views
,您可以用exists
,它會延遲計算,避免了環路的不必要的執行:
def foo(x: Int, fn: (Int, Int) => Boolean): Boolean = {
(for {
i <- (0 until x).iterator
j <- (i + 1 until x).iterator
} yield(i, j)).exists(fn.tupled)
}
您還可以使用map
和flatMap
代替for
和toStream
或view
,而不是iterator
:
(0 until x).view.flatMap(i => (i + 1 until x).toStream.map(j => i -> j)).exists(fn.tupled)
您還可以在任何收藏上使用view
來獲得所有變形金剛懶惰執行的集合。這可能是短路收集遍歷的最常用的方式。從the docs on views
:
Scala集合默認情況下,嚴格在其所有的變壓器,除了Stream
,它懶洋洋地實現其所有變壓器的方法。但是,有一種系統的方法可以將每個收藏集變成懶惰的收藏集,反之亦然,這是基於收集的意見。視圖是一種特殊的集合,它代表了一些基本集合,但是卻懶散地實現了所有變形。
就開銷而言,它確實取決於具體細節!不同的集合具有可能在開銷量上有所不同的view
,toStream
和iterator
的不同實現。如果fn
計算起來非常昂貴,那麼這個開銷可能是值得的,並且爲您的代碼保留一致的,慣用的功能樣式使其更具可維護性,可調試性和可讀性。如果您處於需要極端優化的情況下,您可能需要回退到return
等較低級別的構造(這不是沒有它自己的開銷!)。
你可以看看尾遞歸 – cchantep