scala ++?
org.apache.spark.ml.recommendation.ALS 里有這麼一段代碼:
一直看不懂。我理解成這樣的結構(iter是scala.collection.Iterator)
iter.flatMap { r =&>
val srcBlockId = srcPart.getPartition(r.user)
val dstBlockId = dstPart.getPartition(r.item)
val idx = srcBlockId + srcPart.numPartitions * dstBlockId
val builder = builders(idx)
builder.add(r)
if (builder.size &>= 2048) { // 2048 * (3 * 4) = 24k
builders(idx) = new RatingBlockBuilder
Iterator.single(((srcBlockId, dstBlockId), builder.build()))
} else {
Iterator.empty
}
} ++ {
builders.view.zipWithIndex.filter(_._1.size &> 0).map { case (block, idx) =&>
val srcBlockId = idx % srcPart.numPartitions
val dstBlockId = idx / srcPart.numPartitions
((srcBlockId, dstBlockId), block.build())
}
}
iter.flatMap { } ++ { }
,但是不理解++前後之間的關係,以及源碼中兩部分{}的邏輯。
看到 scala ++ 還以為這個號稱JVM上面的C++的貨又向C++邁進了一步呢,笑死我了。
笑完還是答一下兒吧:
要看明白這段代碼,得明白code block在scala裡面是什麼東西。第一個花括弧里:iter.flatMap { r =&>
這個code block由於以參數列表開始,所以這個block是一個函數。flatMap() 這個函數接收一個函數參數,把它應用到iter裡面的元素。這一段沒啥問題吧,最終返回一個Iterator[((Int, Int), ALS.RatingBlock)]第二個花括弧,又是code block的另一種用法……給這段代碼的作者默默點個贊……A code block is a sequence of statements that are executed and result the last statement is returned.裡面經過zip, filter, map (這裡的花括弧又是一個匿名函數) 之後,結果又是一個Iterator[((Int, Int), ALS.RatingBlock)] 因為這是code block裡面最後一個語句的結果,其作為整個code block的返回值。然後這個++就容易理解了,兩端都是Iterator,可以用++操作連接……
看完這個代碼,我又難以抑制地想念了一下兒山野中隱居的 lisp……
參考文獻:
http://daily-scala.blogspot.com/2010/05/return-value-of-block.htmliter.flatMap { ... } 和 { builders.view.zipWithIndex.filter(_._1.size &> 0).map { ... } } 各自返回一個 Iterator[((Int, Int), ALS.RatingBlock)],於是 ++ 把兩個 Iterator[((Int, Int), ALS.RatingBlock)] 合併成一個集合。
你要問的是什麼?推薦閱讀: