2017-07-09 2 views
-3

J'ai quelques problèmes avec une opération foreach: le programme ne se termine jamais et c'est comme si il était dans l'impasse sur cette ligne.Foreach Deadlock dans Scala

C'est la ligne de code du programme est bloqué sur, où j'ai d'imprimer le premier élément du rddData pour chaque élément de rddUserData:

rddUserData.foreach(r => println(trasformToIndexed().lookup(0)(0)._2.toDouble)) 

Voici le code de la fonction trasformToIndex:

def trasformToIndexed(): RDD[(Long, ((String, String), Int))] = { 
     val withIndex = rddData.zipWithIndex() 
     val indexKey = withIndex.map{case (k,v) => (v,k)} 
     indexKey 
    } 

J'ai aussi essayé de cette façon, en utilisant withouth zipWithIndex, mais tournant le RDD dans une liste, puis obtenir le premier élément, mais il ne fonctionne pas non plus:

rddUserData.foreach(r => println(rddData.collect().toList(0)._2).toDouble) 

La seule façon d'atteindre mon but est de parcourir la rddUserData par un for statement, et faire les mêmes opérations.

val listReaction = rddUserData.collect().toList 
for(i<-0 to listReaction.size-1){ 
    println(println(rddData.collect().toList(0)._2).toDouble) 
} 

Cependant, je voudrais le résoudre avec une déclaration foreach.

+1

J'ai du mal à voir comment le premier bloc de code est équivalent au dernier bloc. – erip

+0

Salut, merci d'avoir répondu. Quoi qu'il en soit, bien sûr, ils sont différents pour la façon dont je récupère le premier élément du rdd, mais en fait le dernier bloc de code ne va pas dans l'impasse, tandis que le premier le fait. Le dernier bloc de code celui ci-dessus utilise de la même façon pour prendre le premier élément de la rddData. – xcsob

+1

Qu'est-ce que ''rddData'? Pourquoi appelez-vous 'collect' à chaque itération? Pourquoi appelez-vous TOUT (semble que vous avez juste besoin de 'rddData.first'). Vous ne semblez pas avoir besoin d'un 'foreach' non plus, car le corps ne dépend pas de l'entrée ... – Dima

Répondre

0

Mon problème était l'accès de rddData à l'intérieur du foreach de rddUserData. Évidemment, cela n'est pas possible à l'intérieur d'une fermeture.

Quoi qu'il en soit, je posterai ma solution ici:

  1. J'ai créé une carte pour le rddData; Je l'ai accédé à l'intérieur du foreach.
 
val map = rddData.collect().toMap 
rddUserData.foreach(println(rddData.get("someKey")).toDouble) 

La fonction get retourne un objet Certains, de sorte que vous devez déballer.

+0

Et échouera si rddData est grand. Ce qui est probablement, puisque c'est pourquoi on utilise Spark. Donc, ce n'est pas vraiment une solution? –

+0

Oui, vous avez raison. Mais, en fait, j'ai besoin de chercher dans un rdd par un champ, et je dois le faire à l'intérieur d'un forEach dans un autre rdd. Mon problème est: comment rechercher par champ dans un rdd? J'avais résolu ce problème en faisant un filtre puis en prenant le premier élément du rdd, mais il semble très lent. Avez-vous des conseils? – xcsob

+0

"comment rechercher par champ dans un rdd?" Normalement, vous n'avez pas (ou du moins, pas un par un) - vous utilisez un 'join' ou quelque chose pour obtenir toutes les informations qui vous intéressent). Pouvez-vous expliquer votre cas d'utilisation global de manière plus détaillée?S'il vous plaît essayez de le décrire en termes de transformations de l'ensemble RDD, et donnez quelques exemples d'entrées et de sorties désirées - 'foreach', puis quelque chose qui gâte avec un seul élément est à peu près une odeur de code sauf si vous le faites pour Effets secondaires. –