Wie kann ich einen Hash von Hashes in Ruby durchlaufen?

80

OK, also ich habe diesen Hash

 h
 => {"67676.mpa"=>{:link=>"pool/sdafdsaff", :size=>4556}} 

>  h.each do |key, value|
>     puts key
>   puts value
>   end
67676.mpa
linkpool/sdafdsaffsize4556

Wie greife ich auf die separaten Werte im Wert-Hash in der Schleife zu?

Matt Elhotiby
quelle
1
Was möchten Sie als Ausgabe sehen?
Mark Thomas
Der Appcoach Shingara hat super geklappt ... ich muss einen Rohling gezogen haben ... die Antwort war direkt vor mir ... ich musste eine innere Schleife machen
Matt Elhotiby
Es ist bekannt, dass die Ausgabe von Puts auf einen Hash ziemlich nutzlos ist. Haben Sie versucht, "Puts hash.inspect" durchzuführen?
Tokand

Antworten:

158

Der Wert ist ein Hash, daher müssen Sie ihn iterieren, oder Sie können nur Werte abrufen: -

h.each do |key, value|
  puts key
  value.each do |k,v|
    puts k
    puts v
  end
end

oder

h.each do |key, value|
  puts key
  value.values.each do |v|
    puts v
  end
end

Shingara
quelle
Was ist, wenn der Schlüssel nirgendwo verwendet wird? . Müssen wir einen ?Schlüssel ersetzen? Beispiel: |?, array|Ist diese Syntax gültig für Ruby?
Huzefa Biyawarwala
@huzefabiyawarwala Wenn der Schlüssel nicht in der Iteration verwendet wird, sollten Sie ihm einen Unterstrich wie diesen voranstellen|_key, value|
Severin
17

Sie möchten den Hash erneut verwenden. Hier ist eine rekursive Methode:

def ihash(h)
  h.each_pair do |k,v|
    if v.is_a?(Hash)
      puts "key: #{k} recursing..."
      ihash(v)
    else
      # MODIFY HERE! Look for what you want to find in the hash here
      puts "key: #{k} value: #{v}"
    end
  end
end

Sie können dann jeden Hash nehmen und ihn weitergeben:

h = {
    "x" => "a",
    "y" => {
        "y1" => {
            "y2" => "final"
        },
        "yy1" => "hello"
    }
}
ihash(h)
Travis Reeder
quelle
Was ist, wenn der Schlüssel nirgendwo verwendet wird? . Müssen wir einen ?Schlüssel ersetzen? Beispiel: |?, array|Ist diese Syntax gültig?
Huzefa Biyawarwala
Behalte es, benutze es einfach nicht. Fragezeichen ist ungültig.
Travis Reeder
7

Ich habe Travis 'Antwort kaum verbessert. Wie wäre es mit diesem Kern:

https://gist.github.com/kjakub/be17d9439359d14e6f86

class Hash

  def nested_each_pair
    self.each_pair do |k,v|
      if v.is_a?(Hash)
        v.nested_each_pair {|k,v| yield k,v}
      else
        yield(k,v)
      end
    end
  end

end

{"root"=>{:a=>"tom", :b=>{:c => 1, :x => 2}}}.nested_each_pair{|k,v|
  puts k
  puts v
}
Jakub Kuchar
quelle
@Travis R verbesserte Antwort
Jakub Kuchar
5

Der einfachste Weg, in diesem Fall alle drei Werte zu trennen, wäre wie folgt:

h.each do |key, value|
  puts key
  puts value[:link]
  puts value[:size]
end
Jeremy Lynch
quelle
2

Sie können direkt auf die Werte eines Hash zugreifen, indem Sie aufrufen hash.values. In diesem Fall könnten Sie so etwas tun

> h = {"67676.mpa"=>{:link=>"pool/sdafdsaff", :size=>4556}}
> h.values.each do |key, value|
>   puts "#{key} #{value}"
> end

link pool/sdafsaff
size 4556
roo
quelle