2009-08-04 8 views
184

다음과 같은 해시가 있습니다.Ruby에서 해시를 반복하는 방법은 무엇입니까?

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

어떻게 이런 식으로 출력을 얻을 수 있습니까?

1----- 

a 

b 

2----- 

c 

3----- 

a 

d 

f 

g 
+3

해시를 반복 처리하고 주문할 것으로 예상되는 경우 다른 컬렉션 유형 –

+0

을 사용해야합니다. 해시 값을 라디오 버튼 옵션으로 전달할 수 있습니까 ?? – sts

+0

라디오 버튼 옵션으로 해시를 전달 중입니다. 첫 번째 옵션의 경우 라디오 버튼을 가져 오는 중입니다. 다른 값은 가져 오지 못합니다. – sts

답변

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

, 그 (실제로는 Fixnum의 해시 함수에 의해 정의 된 순서대로) 무작위 순서로 반복 될 것이며, 1.9에서는 문자 순서대로 반복 될 것입니다. 해시의 종류를 호출

+1

을 참조하십시오. 키가 어디에도 사용되지 않는다면 어떻게 될까요? . 열쇠 대신에'?'를 써야합니까? 예 :'|?, array |'이 유효한 구문입니까? –

+0

@huzefabiyawarwala 아니요, '?'는 Ruby에서 유효한 변수 이름이 아닙니다. 당신은'_'을 사용할 수는 있지만, *는 필요 없습니다. – sepp2k

+0

해쉬를 반복하기 위해'| k, v |'를 사용했다면 우리의 논리 구현에서'k'를 사용하지 않았기 때문에'| k, v |'와 같이 작성할 수 있습니다. _, v |'? –

47
hash.keys.sort.each do |key| 
    puts "#{key}-----" 
    hash[key].each { |val| puts val } 
end 
16

중첩 배열로 변환하고 그래서 당신이 필요로하는 모든이입니다 키를 정렬합니다

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

그리고 당신이하지 않으면 실제로 "필요 - - "부분은, 그것은 단지가 될 수 있습니다

puts h.sort 
+0

해시 키는 숫자이므로 '[k + "----"]'는 TypeError를 발생시킵니다 (문자열을 Fixnum으로 강제 변환 할 수 없음).'[k.to_s + "----"]' –

+0

사실 충분합니다. 테스트 버전에는 편지가있었습니다. 더 나은 "# {k} ----"을 사용하여 고정되었습니다. –

+0

현재 나열된 답변 중 가장 좋은 답변입니다. –

67

해시를 반복하는 가장 기본적인 방법은 다음과 같습니다

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

Hash::each도 가능하므로 재귀 열거 형을 지원합니다. 여기

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 

이 사용 예와 recursive 플래그없이 Hash::each : 여기 블록열거 지원 Hash::each (Hash::each_pair)의 내 버전이

여기
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::merge (Hash::merge!) here을 살펴보십시오.

관련 문제