2016-07-28 27 views
0

I haben die folgenden:Rubin .map! oder die jeweils für ein Array anstelle Modifizieren

article_results.keys do |key| 
    article_results[key].map! do |a| 
    a[:filename] = c.filename 
    a[:sitename] = c.site_name 
    a 
    end 
end 

wie ich will jedem Element jedes Arrays innerhalb des Hash-dynamisch, aber aus irgendeinem Grund a[:filename] und a[:sitename] sind leer hinzuzufügen, wenn sie benutzt.

Also ich möchte wissen, ob ich stattdessen .each verwenden sollte. Ich würde auch gerne wissen, was der Hauptunterschied ist, da beide für Nebenwirkungen verwendet werden können.

Ich füge das als ein zusätzliches fyi hinzu, ich benutze Ruby 1.8.7, also wäre es schön zu wissen, wie es sich zwischen den Versionen (1.8.7 - 1.9+) unterscheidet.

Ps.s. Ich weiß, was der Unterschied zwischen .each und .map ist, frage ich speziell über .map!.

Antwort

0

#map hat eine etwas andere Semantik für Hashes als für Arrays (und ich denke, es ist nicht sehr konsistent zwischen Versionen von Ruby). in der Regel, wenn Sie für ein Array als Folge einer Operation suchen - #map ist dein Freund, aber wenn Sie Hash als Folge einer Operation wollen - du bist besser dran mit #reduce:

article_results.reduce({}) do |hash, (key, value)| 
    hash.merge(key => value.merge(filename: c.filename, 
           sitename: c.sitename)) 
end 

alternativ, wenn

article_results.each do |key, value| 
    article_results[key].merge!(filename: c.filename, 
           sitename: c.sitename) 
end 
+0

ich vergesse immer wieder, es gibt einen Unterschied zwischen 1.8.7 (die ich zur Zeit zu verwenden, gezwungen ist) und 1.9+, ich: Sie mich nicht, wie „funktional“ Ihr Code ist, können Sie #each verwenden Ich füge das dem op hinzu. reduzieren sieht aus wie spritzen, ist das das gleiche? Article_results ist ein Hash von Arrays von Objekten mit Hash-ähnlichen Settern und Gettern, um zusätzliche Daten hinzuzufügen. – Thermatix

+0

korrigieren, reduzieren ist Alias ​​zu injizieren (oder umgekehrt). es ist nur eine Frage der kohärenten Benennung - Karte geht mit reduzieren, injizieren geht mit sammeln. Aus Code in Ihrer Frage sieht es so aus, dass "artice_results" ein Hash von Hashes ist (oder Objekten, die sich wie Hashes verhalten), also sollte 'merge!' auf ihnen funktionieren. wenn nicht - benutze einfach '[] =' direkt. – keymone

+0

Wenn 'article_results' ein Hash von Arrays ist, dann ist Ihr' map! '- Code korrekt und Sie sollten sicherstellen, dass' c.filename' gültig ist. und ofc '.keys' nimmt keinen Block, muss' .keys.each' – keymone