2010-12-10 6 views
31

어떻게 해시 안에 배열을 초기화 할 수 있습니까?

같은 해시 배열을 초기화하려면 노력하고 있어요

@my_hash = Hash.new(Array.new) 

그렇게 할 수 있습니다 :

@my_hash["hello"].push("in the street") 
=> ["in the street"] 
@my_hash["hello"].push("at home") 
=> ["in the street", "at home"] 
@my_hash["hello"] 
=>["in the street", "at home"] 

문제는 모든 새 해시 키 반환 또한 ["in the street", "at home"]

@my_hash["bye"] 
=> ["in the street", "at home"] 
@my_hash["xxx"] 
=> ["in the street", "at home"] 

! !! ??? ???

배열 해시를 초기화하는 올바른 방법은 무엇이 잘못 되었습니까?

+0

관련 : http://stackoverflow.com/questions/190740/setting-ruby-hash-default-to-a-list – tokland

답변

83
@my_hash = Hash.new(Array.new) 

이가 키를 찾을 수 없습니다 때마다 반환됩니다 정확히 하나 개의 배열 객체를 생성한다. 당신이 오직 그 배열을 돌연변이 새로 만들 결코 때문에, 모든 키가 같은 배열을 매핑합니다.

싶은 것은 :

@my_hash = Hash.new {|h,k| h[k] = Array.new } 

하거나

@my_hash = Hash.new {|h,k| h[k] = [] } 

Hash.new에 블록을 전달 다릅니다 단순히 2 가지 방법으로 인수를 통과하는 :

  1. 을 블록이 키를 찾을 수 없을 때마다 실행됩니다. 따라서 매번 새로운 배열을 얻습니다. 인수와 버전에서, 그 인수 (new를 호출하기 전에) 한 번 평가하고 그 결과는 매번 반환됩니다. 이렇게함으로써

  2. h[k] = 실제로 해시에 키를 삽입합니다. 이렇게하지 않으면 단지 @my_hash[some_key] 접근 실제로 some_key이 해시에 삽입 발생하지 않습니다.

+14

한 잡았다 여기서주의해야 할은 그 지금도 * 검사 *는 키가 그것을 만들 것이고, 그것은 당신이 원하는 것이 아닐 수도 있습니다. 이런 이유로 나는 가끔 정상적으로 (그냥 {}으로) 해쉬를 만들고, (@myhash [ "hello"] || = [])와 같이 호출 할 때 배열 생성을한다. ")'. –

2

Hash.new에 대한 인수는 새로운 해시 키에 대한 기본 값을, 그래서 당신이 그것을 참조를 통과 할 때 참조는 새로운 해시 키에 사용됩니다. 당신은 당신이 전화를 해당 참조 ...

당신은 그것을 값을 밀어 전에 해시 키에 새 참조를 전달해야
hash["key"].push "value" 

...

hash["key1"] = Array.new 
hash["key1"].push "value1" 
hash["key2"] = Array.new 
hash["key2"].push "value2 

당신이 캡슐화 시도해 볼 수도를 업데이트하고 도우미 방법으로도.

7

이 시도 :

@my_hash = Hash.new { |h, k| h[k] = Array.new } 
관련 문제