我有 2 個向量,如下所示。
val vecBase21=....sortBy(r=>(r._1,r._2))
vecBase21: scala.collection.immutable.Vector[(String, String, Double)] = Vector((036,20210624 0400,2.0), (036,20210624 0405,2.0), (036,20210624 0410,2.0), (036,20210624 0415,2.0), (036,20210624 0420,2.0),...)
val vecBase22=....sortBy(r=>(r._1,r._2))
vecBase22: scala.collection.immutable.Vector[(String, String, Double)] = Vector((036,20210625 0400,2.0), (036,20210625 0405,2.0), (036,20210625 0410,2.0), (036,20210625 0415,2.0), (036,20210625 0420,2.0),...)
在里面,x._1 是 ID,x._2 是日期時間,x._3 是值。然后我這樣做來創建第三個向量,如下所示。
val vecBase30=vecBase21.map(x=>vecBase22.filter(y=>x._1==y._1 && x._2==y._2).map(y=>(x._1,x._2,x._3,y._3))).flatten
這實際上是 SQL 中的連接,a join b on a.id=b.id and a.date_time=b.date_time. 它在 vecBase22 中回圈以從 vecBase21 中搜索 ID 和 date_time 的一種組合。由于每個組合在一個向量中都是唯一的并且它們被排序,我想知道 vecBase22 中的回圈是在找到匹配項后停止還是回圈直到 vecBase22 結束。我試過這個
val vecBase30=vecBase21.map(x=>vecBase22.filter(y=>x._1==y._1 && x._2==y._2).map{y=>
println("x1=" x._1 " y1=" y._1 " x2=" x._2 " y2=" y._2)
(x._1,x._2,x._3,y._3)}).flatten
但它顯然只給出匹配的結果。有沒有辦法列印機器評估是否匹配的兩個向量的所有組合?
uj5u.com熱心網友回復:
由于每個組合在一個向量中都是唯一的并且它們被排序,我想知道 vecBase22 中的回圈是在找到匹配項后停止還是回圈直到 vecBase22 結束
當您呼叫時filter,vecBase22您會遍歷該集合的每個元素以查看它是否與謂詞匹配。這將回傳一個新集合并將其傳遞給map函式。如果要縮短過濾程序,可以考慮使用該方法collectFirst(Scala 2.12):
def collectFirst[B](pf: PartialFunction[A, B]): Option[B]
Finds the first element of the traversable or iterator for which the given partial function is defined, and applies the partial function to it.
Note: may not terminate for infinite-sized collections.
Note: might return different results for different runs, unless the underlying collection type is ordered.
pf: the partial function
returns: an option value containing pf applied to the first value for which it is defined, or None if none exists.
Example:
Seq("a", 1, 5L).collectFirst({ case x: Int => x*10 }) = Some(10)
所以你可以這樣做:
val vecBase30: Vector[(String, String, Double, Double)] = vecBase21
.flatMap(x => vecBase22.collectFirst {
case matched: (String, String, Double) if x._1 == matched._1 && x._2 == matched._2 => (x._1, x._2, x._3, matched._3)
})
uj5u.com熱心網友回復:
首先:是的,它遍歷 的所有專案vecBase22,對于 的每個專案vecBase21。這就是地圖和過濾器的作用。
如果 println 不起作用,那可能是因為您在解釋器中執行的代碼丟失了 std。一些筆記本?
此外,如果您希望它在找到匹配項后停止,請使用 Seq.find
最后,您可以提高可讀性。這里有幾個想法:
- 用例類而不是元組
- 在運算子周圍添加空格
- 如果不適合一行,則在每個 monad 操作之前添加新行
- 使用 flatMap 而不是 map 后跟 flatten
- 添加 val 型別(不是必需的,但它有助于閱讀代碼)
這給出了:
case class Item(id: String, time: String, value: Double)
case class Joint(id: String, time: String, v1: Double, v2: Double)
val vecBase21: Vector[Item] = ....sortBy(item => (item.id, item.time))
val vecBase22: Vector[Item] = ....sortBy(item => (item.id, item.time))
val vecBase30: Vector[Joint] = vecBase21.flatMap( x =>
vecBase22
.filter( y => x.id == y.id && x.time == y.time)
.map( y => Joint(x.id, x.time, x.value, y.value))
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/312776.html
