Jak zapętlić mieszankę skrótów?

81

Mam ten hash:

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

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

Jak uzyskać dostęp do oddzielnych wartości w skrócie wartości w pętli?

Matt Elhotiby
źródło
1
Co chciałbyś zobaczyć jako wynik?
Mark Thomas,
aplikacja, której używał shingara, działała świetnie ... muszę narysować puste miejsce ... odpowiedź była tuż przede mną ... musiałem zrobić wewnętrzną pętlę
Matt Elhotiby
dobrze wiadomo, że wynik operacji puts na hash jest całkiem bezużyteczny. Czy próbowałeś użyć opcji „puts hash.inspect”?
tokland,

Odpowiedzi:

161

Wartość jest skrótem do, więc musisz ją iterować lub możesz uzyskać tylko wartości: -

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

lub

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

shingara
źródło
a co jeśli klucz nie jest nigdzie używany? . czy musimy wstawić ?w miejsce klucza? ex: |?, array|czy to poprawna składnia dla Ruby?
huzefa biyawarwala
@huzefabiyawarwala, jeśli klucz nie jest używany w iteracji, należy poprzedzić go podkreśleniem w ten sposób|_key, value|
Severin,
17

Będziesz chciał powtórzyć hasz, oto metoda rekurencyjna:

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

Następnie możesz wziąć dowolny hash i przekazać go:

h = {
    "x" => "a",
    "y" => {
        "y1" => {
            "y2" => "final"
        },
        "yy1" => "hello"
    }
}
ihash(h)
Travis Reeder
źródło
a co jeśli klucz nie jest nigdzie używany? . czy musimy wstawić ?w miejsce klucza? ex: |?, array|czy to poprawna składnia?
huzefa biyawarwala
Zatrzymaj to, po prostu nie używaj. znak zapytania jest nieprawidłowy.
Travis Reeder
7

Nieco poprawiłem odpowiedź Travisa, a co powiesz na to:

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
źródło
@Travis R poprawiona odpowiedź
Jakub Kuchar
5

Najprostszy sposób oddzielenia wszystkich trzech wartości w tym przypadku wyglądałby następująco:

h.each do |key, value|
  puts key
  puts value[:link]
  puts value[:size]
end
Jeremy Lynch
źródło
2

Możesz uzyskać dostęp do wartości skrótu bezpośrednio, dzwoniąc hash.values. W takim przypadku możesz zrobić coś takiego

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

link pool/sdafsaff
size 4556
Maleństwo
źródło