val test_rated = pearson.flatMap(x => {
val bid1 = x._1._1.toInt
val bid2 = x._1._2.toInt
val sim = x._2.toDouble
val pairs = for (tu <- test_users) yield {
val tid = tu.toInt
if (test_map.contains((tid, bid2)) && train_map.contains((tid, bid1))){
((tid, bid2), (bid1, sim))
}
}
pairs
}).filter(row => row!= ())
在此代码块test_users
中是标量list
。经过flatMap
的yield操作之后,我可以得到结果并用foreach
打印。
但是,如果我想再次映射它
test_rated.map(x => x._2)
我无法使用x._2
答案 0 :(得分:1)
假设其余代码正确且类型匹配(如果没有[mcve],则不可能说),这只是在以错误的方式进行操作。让我们简化显示原因的过程:
scala> for {
| x <- 1 to 5
| } yield { if (x % 2 == 0) x}
res0: scala.collection.immutable.IndexedSeq[AnyVal] = Vector((), 2, (), 4, ())
您看到的类型不是Seq[Int]
,而是Seq[AnyVal]
。过滤数据不会改变:
scala> res0.filter(x => x != ())
res1: scala.collection.immutable.IndexedSeq[AnyVal] = Vector(2, 4)
您可以collect
:
scala> res0.collect { case x: Int => x}
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4)
但实际上您应该使用保护表达式:
scala> for {
| x <- 1 to 5 if x % 2 == 0
| } yield x
res3: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4)
因此您的代码应重写为:
val test_rated = pearson.flatMap(x => {
val bid1 = x._1._1.toInt
val bid2 = x._1._2.toInt
val sim = x._2.toDouble
def keep(tid) = {
test_map.contains((tid, bid2)) && train_map.contains((tid, bid1))
}
for {
tid <- test_users.map(_.toInt) if keep(tid)
} yield ((tid, bid2), (bid1, sim))
})
答案 1 :(得分:0)
我相信flatMap()
中的代码块不会对任何对象求值。您应该删除val pairs =
或显式返回pairs
,例如
pearson.flatMap(x => {
...
val pairs = ...
pairs
}).filter(...)