我有一個包含字串和元組串列的地圖:
Map[String, List[(String, Int]]
地圖中的一些線條示例如下所示:
"test1", List(("apple", 0), ("pear", 1), ("banana", 0))
"test2", List(("green", 1), ("yellow", 1), ("red", 0))
"test3", List(("monday", 0), ("tuesday", 1), ("wednesday", 0))
僅當元組串列包含超過 1 個等于 0 的值時,提取每行中第一個字串串列的最佳方法是什么?
換句話說,我想要一個包含“test1”和“test2”的串列,因為這 2 行是唯一在其元組串列中包含超過 1 個“0”的行。
uj5u.com熱心網友回復:
您的出發點將是collector filter; 當你有一個集合并且你想要一個應用了一些條件的新集合時,這兩種方法都很有用。
如前所述,您的條件聽起來像是count在標準庫中幾乎所有集合型別上定義的方法的用例。
這應該作業...
theMapFromYourExample
.collect { case (key, list) if list.count(_._2 == 0) > 1 => key }
.toList
...但有一些考慮因素:
.collect并且toList都將創建新的整個系列。將它們放在一起意味著您通過構建一個中間集合來浪費一些記憶體和 CPU 時間,一旦您的運算式運行完成,該集合就會直接發送到垃圾收集。為了避免為整個中間集合分配記憶體,您可以使用View模式,可通過.view大多數集合上的方法訪問。.count在串列的大小上是 O(N),因為它需要檢查串列中的每個專案以查看它是否與您的條件匹配。由于您只關心計數“至少”是某個值,因此如果超過 1,您可以提前停止計數。該lengthCompare方法對這種情況很有用。
所以這里的代碼大致相同,利用“視圖”來提高效率:
def hasAtLeastTwoZeroes(list: List[(String, Int)]) = {
list
.view // lets us call `.filter` without allocating a new List
.filter(_._2 == 0) // apply conditional: value is 0
.lengthCompare(1) > 0 // like saying `.length > 1`, but is O(1), not O(N)
}
theMapFromYourExample
.view // lets us call `collect` without allocating an intermediate collection
.collect { case (key, list) if hasAtLeastTwoZeroes(list) => key }
.toList // builds a List from the collected view
正如 Luis 在評論中指出的那樣更新sizeIs,Scala 2.13 添加了該方法,該方法的界面比lengthCompare
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/455948.html
