8
votes

Résoudre un problème avec la carte Réduire

Je veux simuler en rubis ma mise en œuvre de la carte code> et Réduire les fonctions code> pour un système comme Hadoop pour vérifier que l'idée fonctionne au moins.

J'ai le problème suivant. J'ai deux listes d'éléments: p> xxx pré>

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>

commonList
5 - A
12 - B
11 - C
16 - D


0 commentaires

4 Réponses :


2
votes

Vous pouvez essayer en considérant les éléments donnés dans Mapreduce Wikipedia Article:

  • Un lecteur d'entrée - dans votre cas, ce serait probablement une méthode d'appel sur [touche, valeur] paire de vos hachages d'entrée.
  • une fonction de carte - Vous avez déjà des touches que vous devez traiter vos données par, donc votre mapper retournerait simplement la touche [clé, valeur] la paire une entrée
  • 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 .
  • 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.
  • une fonction réduite - serait donnée [clé, liste] paire, liste étant la liste des valeurs associées à la clé. Il retournerait la somme de la liste 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).
  • Un écrivain de sortie - pourrait être un hasch uni dans votre exemple.

    et Voici My (Over) Mise en œuvre simplifiée de ce qui précède.


2 commentaires

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} à la place.



2
votes

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 et réduira < / code> celles: xxx

la carte la fonction fonctionnera une paire (lettre, compte) , qui sera regroupé plus tard. Ensuite, pour chaque lettre reçu reçu de mappe s Réduire recevra un tableau contenant chaque compte cédé par une carte pour cela lettre . Comme vous le souhaitez uniquement, si la lettre survient sur les deux hachages, nous avons besoin de compteur s pour apparaître sur partial_counts deux fois pour l'utiliser pour calculer la somme à la fin. La fonction Réduire 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.

Utilisation de ces mapper et Réduisez 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 serait aussi simple que cédant chaque paire de (lettre, compte) : xxx

ou < / p> xxx


0 commentaires

2
votes
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.

0 commentaires

3
votes

Utilisation de IRB (RUBY-1.9.2-P180):

results = [[:a,9], [:b,4]]
Hash[ results ]


0 commentaires