Ошибка несоответствия типа scala в коде graphX

Я новичок в Scala, изучая его для Apache-Spark. Я написал простую функцию в Scala для GraphX

def foo(edge: EdgeTriplet[Map[Long, Double], Double]): Iterator[(VertexId, Map[Long, Double])] = {

    val m = edge.srcAttr

    for((k, v) <- m){
        if (v + edge.attr < edge.dstAttr.getOrElse(k, 10.0))
            Iterator(edge.dstId, Map(k -> v + edge.attr))

        else

            Iterator.empty

    }

}

ошибки

Name: Compile Error
Message: <console>:37: error: type mismatch;
 found   : Double
 required: String
                   Iterator(edge.dstId, Map(k -> v + edge.attr))
                                                          ^
<console>:35: error: type mismatch;
 found   : Unit
 required: Iterator[(org.apache.spark.graphx.VertexId, Map[Long,Double])]
    (which expands to)  Iterator[(Long, Map[Long,Double])]
           for((k, v) <- m){
                      ^
StackTrace:

Почему Скала рассматривает V как строку? а в чем причина второй ошибки?

После редактирования кода, предложенного @Alexey, я получаю сообщение об ошибке

Name: Compile Error
Message: <console>:30: error: type mismatch;
 found   : scala.collection.immutable.Map[org.apache.spark.graphx.VertexId,scala.collection.immutable.Map[Long,Double]]
    (which expands to)  scala.collection.immutable.Map[Long,scala.collection.immutable.Map[Long,Double]]
 required: Iterator[(org.apache.spark.graphx.VertexId, Map[Long,Double])]
    (which expands to)  Iterator[(Long, Map[Long,Double])]
                 (k, v) <- edge.srcAttr
                        ^
StackTrace:

Если это поможет, я реализую другую версию функции sendMessage из этого кода

1 ответ

Во-первых, это общая проблема с + в Скале, к сожалению. В этом случае у вас нет k -> (v + edge.attr), как вы, вероятно, ожидали, но (k -> v) + edge.attr, И единственный + метод на Tuple2 принимает String, Чтобы это исправить, просто добавьте правильные скобки.

Вторая ошибка заключается в том, что for(...) { ... } возвращается Unit (переводится на foreach вызов). Вам не хватает yield, На самом деле, если вы хотите использовать for должно быть что-то вроде

for {
  (k, v) <- m
  x <- if (v + edge.attr < edge.dstAttr.getOrElse(k, 10.0))
      Iterator((edge.dstId, Map(k -> (v + edge.attr))))
    else
      Iterator.empty[(Long, Map[Long,Double])]
} yield x

Я предпочел бы написать это как

m.flatMap { case (k, v) => 
  if (v + edge.attr < edge.dstAttr.getOrElse(k, 10.0))
    Iterator((edge.dstId, Map(k -> (v + edge.attr))))
  else
    Iterator.empty[(Long, Map[Long,Double])]
}
Другие вопросы по тегам