Je veux simuler en rubis ma mise en œuvre de la carte code> et J'ai le problème suivant. J'ai deux listes d'éléments: p> J'ai besoin de créer une liste commune qui inclut la somme des numéros associés aux alphabets communs dans les deux listes: p> Réduire les fonctions code> pour un système comme Hadoop pour vérifier que l'idée fonctionne au moins.
commonList
5 - A
12 - B
11 - C
16 - D
4 Réponses :
Vous pouvez essayer en considérant les éléments donnés dans Mapreduce Wikipedia Article: P>
[touche, valeur] code> paire de vos hachages d'entrée. LI>
- une fonction de carte - Vous avez déjà des touches que vous devez traiter vos données par, donc votre
mapper code> retournerait simplement la touche [clé, valeur] code> la paire une entrée li>
- Une fonction de partition - une méthode qui affecterait un travailleur réduisant en fonction de la clé. Dans votre cas, il pourrait être simplement
clé.hash% réducteur_count code>. Li>
- une fonction de comparaison - Je ne pense pas que ceci est applicable dans votre cas car vous n'avez pas besoin de valeurs à traiter dans un ordre particulier. LI>
- une fonction réduite - serait donnée
[clé, liste] code> paire, liste étant la liste des valeurs associées à la clé. Il retournerait la somme de la liste code> si la liste est supérieure à un élément long (car vous voulez uniquement des éléments apparaissant dans les deux cases d'entrée traitées). LI>
- Un écrivain de sortie - pourrait être un hasch uni dans votre exemple. li>
ul>
et Voici My (Over) Mise en œuvre simplifiée de ce qui précède. P>
J'essaie votre solution, mais je reçois une erreur avec cette ligne: [Key, List.Iject (&: +)]. Je reçois cette erreur: "TypeError: mauvais type d'argument (Proc)"
Vous utilisez probablement plus de rubis. Utilisez list.Inject {| ACC, I | Acr + i} code> à la place.
supposant que nous disposons de toutes les autres fonctions liées à la carte-map-réduction mises en œuvre (lecteur d'entrée, écrivain de sortie, tri global, ...), ce serait la carte la carte Utilisation de ces ou < / p> code> et
réduira < / code> celles:
la fonction code> fonctionnera code> une paire
(lettre, compte) code>, qui sera regroupé plus tard. Ensuite, pour chaque lettre
reçu code> reçu de
mappe code> s
Réduire code> recevra un tableau contenant chaque compte cédé par une carte code> pour cela
lettre code>. Comme vous le souhaitez uniquement, si la lettre survient sur les deux hachages, nous avons besoin de
compteur code> s pour apparaître sur
partial_counts code> deux fois pour l'utiliser pour calculer la somme à la fin. La fonction code> Réduire code> pourrait être mise en œuvre de plusieurs manières. J'ai essayé de le faire comme des simulaires que possible de comprendre, bien que sa mise en œuvre soit très ajustée à ce problème. P>
mapper code> et
Réduisez code> La mise en œuvre retournera le dernier hachage avec des clés et une valeur inversée, ce qui a plus de sens, car il peut y avoir plusieurs lettres avec le même compte. L'entrée serait meilleure si elle inversait des clés et des valeurs inversées aussi. De cette façon,
mapper code> serait aussi simple que cédant chaque paire de
(lettre, compte) code>: p>
list_1 = ["3 - A", "4 - B", "5 - C", "7 - D", "8 - F"] list_2 = ["2 - A", "8 - B", "6 - C", "9 - D", "4 - E"] (list_1 + list_2).map do |str| # change array of strings to array in the form of [[name, value], ...] str =~ /(\d+) - (.*)/ && [$2, $1.to_i] end.reduce({}) do |memo, obj| # use a temporary Hash to sum up the values; # the value is an array in the form of [value_counter, iteration_counter] prev = memo[obj.first] || [0, 0] memo[obj.first] = [prev.first + obj.last, prev.last + 1] memo end.map do |key, value| # convert to array in original format or # nil, if occurred only once value.last > 1 ? "#{key} - #{value.first}" : nil end.compact => ["A - 5", "B - 12", "C - 11", "D - 16"] This code uses the map and reduce methods of Ruby, but doing all this directly on a Hash would be much more elegant.
Utilisation de IRB (RUBY-1.9.2-P180):
results = [[:a,9], [:b,4]] Hash[ results ]