2017-01-03 6 views
-1

Ich habe unter Array, die gleiche Schlüsselwerte wie {'Hunde' => 11, 'Katzen' => 3} zusammenfassen muss. Um die gleichen Schlüsselwerte in Ruby zusammenzufassen

animals = [['dogs', 4], ['cats', 3], ['dogs', 7]] 

Ich habe die unten Antwort gefunden, während ich auf Stackoverflow gesucht (ich den Link :(verloren)

print animals.each_with_object(Hash.new(0)) { |(k, v), h| h[k] += v } 

Allerdings kann ich es nicht in meinem Kopf klar machen, dass das, was sie k, v und h genau. Denn "h" zweite Argument des Blockcodes zu bleiben, aber es continious mit h [k]. Könnte jemand den Code eindeutig erklären?

Danke zu viel.

Antwort

3

In s imple terms:

animals.each_with_object(Hash.new(0)) do |(key, value), hash| 
    hash[key] += value 
end 

(k,v) Hier ist eine Erweiterung von jedem Paar in dem animals hash, das ist Schlüsselwert. h repräsentiert das "Objekt", das mit dieser Iteration übergeben wurde.

Das ist ein ziemlich Standardmuster in Bezug auf Ruby-Code.

+0

Sie für Ihre prompte Antwort danken. Was soll ich oben Code hinzufügen, einfach um das Ergebnis an cmd zu drucken (ich meine für "do", "end" -Syntax)? – Syildiz

+0

In Ruby gibt es 'puts', mit denen Strings angezeigt werden. Wenn Sie das Ergebnis einer Variablen zuordnen, können Sie 'puts result.inspect' eingeben, wobei 'result' das ist, was Sie zuweisen. Die Debug-freundliche 'p' Methode ist noch einfacher,' p result' ist äquivalent zu dieser anderen Version. – tadman

2
animals.map(&:dup). 
     group_by(&:shift). 
     map { |k, v| [k, v.flatten.inject(:+)] }. 
     to_h 
#⇒ {"dogs"=>11, "cats"=>3} 
+0

Das ist, was ich dachte, aber es sieht viel wie Alchemie aus, wenn es vollständig ausgedrückt wird. Es erzeugt auch viel mehr Müll als 'each_with_object'. – tadman

+0

@tadman in der Tat, aber was ich in erster Linie dachte, war bereits in Ihrer Antwort zur Verfügung gestellt, also war ich auf etwas anderes kommen. Ich würde definitiv für deine Antwort stimmen. – mudasobwa

+0

Auch ist nicht "Enumerable # sum" spezifisch eine 'Rails' Methode? Da es hier kein "rails" -Tag gibt, wäre "reduce (: +)" passender. – engineersmnky

1

Herumspielen mit dem Array es besser zu verstehen

animals.each {|arr| puts arr.inspect } 
# ["dogs", 4] 
# ["cats", 3] 
# ["dogs", 7] 

animals.each {|k, v| puts "k -> #{k}, v -> #{v}" } 
# k -> dogs, v -> 4 
# k -> cats, v -> 3 
# k -> dogs, v -> 7 

animals.each_with_object({}) do |(k, v), h| 
    puts "k -> #{k}, v -> #{v}, h -> #{ h.inspect }" 
end 
# k -> dogs, v -> 4, h -> {} 
# k -> cats, v -> 3, h -> {} 
# k -> dogs, v -> 7, h -> {} 

animals.each_with_object({}) do |(k, v), h| 
    h[v] = k 
    puts "k -> #{k}, v -> #{v}, h -> #{ h.inspect }" 
end 
# k -> dogs, v -> 4, h -> {4=>"dogs"} 
# k -> cats, v -> 3, h -> {4=>"dogs", 3=>"cats"} 
# k -> dogs, v -> 7, h -> {4=>"dogs", 3=>"cats", 7=>"dogs"} 
Verwandte Themen