2008-10-04 3 views
34

Ruby에서 해시 해시를 만들면 편리한 두 가지 (또는 그 이상의) 차원 검색이 가능합니다. 그러나 삽입 할 때 항상 첫 번째 인덱스가 해시에 이미 있는지 확인해야합니다. 예를 들어 :해시의 해시 관용구 루비?

h = Hash.new 
h['x'] = Hash.new if not h.key?('x') 
h['x']['y'] = value_to_insert 

그것은 새로운 해시가 자동으로 생성되는 경우 다음을 수행하는 것이 바람직 할 것입니다 : 마찬가지로

h = Hash.new 
h['x']['y'] = value_to_insert 

, 첫 번째 인덱스가 존재하지 않는 값을 찾을 때, '[]'오류에 대해 정의되지 않은 메서드를받는 대신 nil이 반환되는 것이 좋습니다.

looked_up_value = h['w']['z'] 

이 동작을하는 Hash 래퍼 클래스를 만들 수는 있지만이 작업을 수행하기위한 기존 루비 관용구가 있습니까? 물론

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

,이 재귀 적으로 수행 할 수 있습니다

+0

해시가 있습니까 특정 깊이 이후에 0을 반환하는 해시 관용구? (저는 물건을 세고 h [: foo] [: bar] [: baz] + = 1) –

답변

54

당신은 Hash.new 기능을 조회 된 값이 아직 존재하지 않는 경우 디폴트 값을 산출하기 위해 실행되는 블록을 전달할 수 있습니다.

/EDIT : 와우,이 질문에 대한 대답은 an article입니다. 완성도를 위해서

, 여기에 임의의 깊이 해시의 기사에서 해결책 :

hash = Hash.new(&(p=lambda{|h,k| h[k] = Hash.new(&p)})) 

크레딧 Data Noise에서 켄트로 이동합니다.

+1

와우. 인상적입니다. –

+0

데드 링크. 인상적인 솔루션. –

+1

죽은 링크가 여기에 전환되었습니다 http://inquirylabs.com/blog2009/2006/09/20/ruby-hashes-of-arbitrary-depth/ – Autodidact

4

Autovivification은 불렀지 만 축복이자 저주입니다. 문제는 정의되기 전에 값을 "살펴보면"이 빈 해시가 슬롯에 붙어있어 나중에 제거해야한다는 것입니다.

당신이 무정부 조금 괜찮다면, 당신은 당신이 그것을 쿼리대로 예상되는 구조를 구축 할 수 있도록 스타일 선언이나-동일에서 언제나 잼 수 있습니다

((h ||= { })['w'] ||= { })['z'] 
관련 문제