Rubyでハッシュを反復する特定の出力を取得するにはどうすればよいですか?


218

Rubyハッシュを反復する特定の出力を取得したい。

これは私が繰り返したいハッシュです:

hash = {
  1 => ['a', 'b'], 
  2 => ['c'], 
  3 => ['d', 'e', 'f', 'g'], 
  4 => ['h']
}

これは私が取得したい出力です:

1-----

a

b

2-----

c

3-----

d 

e

f

g

4-----

h

Rubyでは、どのようにしてHashでそのような出力を取得できますか?


3
ハッシュを反復していて、それが順序付けされることを期待している場合、おそらく他のコレクション型を使用する必要があります
Allen Rice

ハッシュ値をラジオボタンオプションとして渡すことができますか?
STS

ハッシュをラジオボタンオプションとして渡していますが、最初のオプションではラジオボタンが取得されていますが、他の値では取得されていません。
STS

1
@アレン:ハッシュはRuby 1.9で注文されます。Railsはまた、Ruby <1.9を使用している場合、OrderedHashを提供します(これは控えめにしか使用しません)。culann.com/2008/01/rails-goodies-activesupportorderedhash
James

回答:


323
hash.each do |key, array|
  puts "#{key}-----"
  puts array
end

追加すべき順序については、1.8ではアイテムはランダムな順序(実際には、Fixnumのハッシュ関数で定義された順序)で反復されますが、1.9ではリテラルの順序で反復されます。


1
ここで、キーがどこでも使用されていない場合はどうなりますか?。?キーの代わりにを置く必要がありますか?例:|?, array|この構文は有効ですか?
huzefa biyawarwala 2016年

1
@huzefabiyawarwalaいいえ、?Rubyでは有効な変数名ではありません。を使用できますが_、使用する必要ありません。
sepp2k 2016年

2
@huzefabiyawarwalaはい、書くことができます|_, v|
sepp2k

1
vまたは値の代わりに変数名配列を使用するものは何ですか?
jrhicks 2017年

1
@jrhicks OPには値が配列であるハッシュがあるため。
Radon Rosborough、2017年

85

ハッシュを反復する最も基本的な方法は次のとおりです。

hash.each do |key, value|
  puts key
  puts value
end

ええ、これは理にかなっています。@ sepp2kの回答のキーに#{}があるのはなぜですか?
committedandroider

ああ気にしません。私はそれが文字列の補間のためだったことを見た
committedandroider


18

ハッシュでsortを呼び出すと、ネストされた配列に変換され、キーでソートされるため、必要なのは次のとおりです。

puts h.sort.map {|k,v| ["#{k}----"] + v}

そして、実際に「----」の部分が必要ない場合は、次のようにすることができます。

puts h.sort

ハッシュキーは数値なので、 '[k + "----"]'はTypeErrorを発生させます(文字列をFixnumに強制することはできません)。'[k.to_s + "----"]'が必要
です

十分だ。テスト版に手紙がありました。さらに改善された「#{k} ----」を使用して修正。
グレン・マクドナルド

10

私の1行のソリューション:

hash.each { |key, array| puts "#{key}-----", array }

とても読みやすいと思います。


1

再帰的な列挙をサポートするように調整 することもできます。これは、ブロック列挙子をサポートする()の私のバージョンです。Hash::eachHash::eachHash::each_pair

module HashRecursive
    refine Hash do
        def each(recursive=false, &block)
            if recursive
                Enumerator.new do |yielder|
                    self.map do |key, value|
                        value.each(recursive=true).map{ |key_next, value_next| yielder << [[key, key_next].flatten, value_next] } if value.is_a?(Hash)
                        yielder << [[key], value]
                    end
                end.entries.each(&block)
            else
                super(&block)
            end
        end
        alias_method(:each_pair, :each)
    end
end

using HashRecursive

ここでの利用しているHash::each場合とない場合recursiveのフラグは:

hash = {
    :a => {
        :b => {
            :c => 1,
            :d => [2, 3, 4]
        },
        :e => 5
    },
    :f => 6
}

p hash.each, hash.each {}, hash.each.size
# #<Enumerator: {:a=>{:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}, :f=>6}:each>
# {:a=>{:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}, :f=>6}
# 2

p hash.each(true), hash.each(true) {}, hash.each(true).size
# #<Enumerator: [[[:a, :b, :c], 1], [[:a, :b, :d], [2, 3, 4]], [[:a, :b], {:c=>1, :d=>[2, 3, 4]}], [[:a, :e], 5], [[:a], {:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}], [[:f], 6]]:each>
# [[[:a, :b, :c], 1], [[:a, :b, :d], [2, 3, 4]], [[:a, :b], {:c=>1, :d=>[2, 3, 4]}], [[:a, :e], 5], [[:a], {:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}], [[:f], 6]]
# 6

hash.each do |key, value|
    puts "#{key} => #{value}"
end
# a => {:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}
# f => 6

hash.each(true) do |key, value|
    puts "#{key} => #{value}"
end
# [:a, :b, :c] => 1
# [:a, :b, :d] => [2, 3, 4]
# [:a, :b] => {:c=>1, :d=>[2, 3, 4]}
# [:a, :e] => 5
# [:a] => {:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}
# [:f] => 6

hash.each_pair(recursive=true) do |key, value|
    puts "#{key} => #{value}" unless value.is_a?(Hash)
end
# [:a, :b, :c] => 1
# [:a, :b, :d] => [2, 3, 4]
# [:a, :e] => 5
# [:f] => 6

これは質問自体の例です:

hash = {
    1   =>  ["a", "b"], 
    2   =>  ["c"], 
    3   =>  ["a", "d", "f", "g"], 
    4   =>  ["q"]
}

hash.each(recursive=false) do |key, value|
    puts "#{key} => #{value}"
end
# 1 => ["a", "b"]
# 2 => ["c"]
# 3 => ["a", "d", "f", "g"]
# 4 => ["q"]

また、こちらHash::mergeHash::merge!)の再帰バージョンもご覧ください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.