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 ]