루비에서 해시를 반복하는 특정 출력을 얻는 방법은 무엇입니까?


218

Ruby Hash를 반복하는 특정 출력을 얻고 싶습니다.

이것은 반복하고 싶은 해시입니다.

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

루비에서 어떻게 내 해시와 같은 출력을 얻을 수 있습니까?


3
해시를 반복하고 주문할 것으로 예상되는 경우 다른 컬렉션 유형을 사용해야합니다.
Allen Rice

라디오 버튼 옵션으로 해시 값을 전달할 수 있습니까 ??
sts

라디오 버튼 옵션으로 해시를 전달하고 있습니다..하지만 첫 번째 옵션의 경우 라디오 버튼을 받고 있습니다. 다른 값은 얻지 못합니다.
sts

1
@Allen : 해시는 Ruby 1.9에서 주문됩니다. 또한 Rails는 Ruby <1.9 인 경우 OrderedHash를 제공합니다. 참조 culann.com/2008/01/rails-goodies-activesupportorderedhash
제임스 A. 로젠에게

답변:


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

순서에 관해서는 1.8에서 항목이 무작위 순서로 반복됩니다 (실제로 Fixnum의 해싱 함수로 정의 된 순서로) .1에서 1.9에서는 리터럴 순서로 반복됩니다.


1
여기서 키를 어디에도 사용하지 않으면 어떻게됩니까? . ?키 대신에 넣어야 합니까? 예 : |?, array|이 유효한 구문입니까?
huzefa biyawarwala

1
@huzefabiyawarwala 아니요, ?Ruby에서 유효한 변수 이름이 아닙니다. 을 사용할 수 _있지만 꼭 그럴 필요 는 없습니다 .
sepp2k

2
@huzefabiyawarwala 네, 글을 쓸 수 있습니다|_, v|
sepp2k

1
v 또는 value 대신 변수 이름 배열을 사용하는 것은 무엇입니까?
jrhicks

1
@jrhicks OP에는 값이 배열 인 해시가 있기 때문에.
Radon Rosborough

85

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

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

그렇습니다. @ sepp2k의 답변에 키에 # {}이있는 이유는 무엇입니까?
committedandroider

오 괜찮아 나는 그것이 문자열 보간 것을보고
committedandroider

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

18

해시에서 sort를 호출하면 중첩 배열로 변환 한 다음 키별로 정렬하므로 필요한 것은 다음과 같습니다.

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

실제로 "----"부분이 필요하지 않은 경우 다음과 같습니다.

puts h.sort

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

충분합니다. 시험판에 편지가있었습니다. 더 나은 "# {k} ----"를 사용하여 수정했습니다.
glenn mcdonald

10

내 한 줄 솔루션 :

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::eachrecursive

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!) 여기를 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.