2011-03-31 4 views
3

다음과 같은 두 개의 해시 테이블이있는 클래스가 여러 개 있습니다. 두 매핑에는 동일한 키 집합이 있어야합니다. 내 문제는이 구조를 가진 많은 클래스가 있고 시간이 지남에 따라 키 세트가 변경된다는 것입니다.키를 복제하지 않고 데이터 구조 만들기

mapping_1[:key_1] 
mapping_1.index("attr_2_1") #(Ruby 1.8.7) 
mapping_2[:key_3] 
:

mapping_1 = { 
    :key_1 => "attr_1_1", 
    :key_2 => "attr_2_1", 
    :key_3 => "attr_3_1" 
} 

mapping_2 = { 
    :key_1 => "attr_1_2", 
    :key_2 => "attr_2_2", 
    :key_3 => "attr_3_2" 
} 

내가 모두 매핑과 즉 매핑 1. 값에서 키에 대한 키 주어진 값에 액세스 할 수 있어야합니다, 나는이 작업을 수행 할 수 있어야합니다

질문 : 두 구조 모두에서 키를 쓰지 않아도되는 방법이 있습니까?

나는 배열 ( :key_1 => ["attr_1_1", "attr_1_2"])의 열쇠지도를 가지고 생각하지만 난 명령 mapping_1.index()을 실행할 때 내가 두 번째 속성의 값이 무엇인지 모르기 때문에이 작동하지 않습니다.

답변

1

난 분명히 자신의 해시 클래스를 만들고 Hash 대신 사용해야한다고 생각합니다. 키 세트를 처리하고 오브젝트 단위 저장 영역을 랩핑합니다. Hash 방법을 해내는 것입니다 당신이 당신의 컨테이너 클래스에서 사용하는 것이

def self.add_key(key, default_value) 
def self.remove_key(key) 

및 인스턴스 방법 :

def get(key) 
def set(key, value) 
def find_key(value) 

등이 같은 당신의 키 집합을 편집 할 클래스 메소드를 가질 수

물론 평범한 스토리지에 Hash을 사용할 수 있습니다. 새 키를 인스턴스에 추가 할 때마다 키 집합을 확장해야하는 경우 add_keyset에서 호출하면됩니다.

1

아래의 내 a과 같은 다차원 배열을 사용할 수 있습니다. Ruby의 배열 메소드를 사용하면 필요한 것을 할 수 있습니다. 나는 find_all을 사용했고 아마도 더 직접적인 것조차있을 것입니다. 당신이 만든 경우 물론

irb(main):049:0> a 
=> {"key1"=>["attr1_a", "attr1_b"], "key2"=>["attr2_a", "attr2_b"]} 
irb(main):050:0> a['key2'] 
=> ["attr2_a", "attr2_b"] 
irb(main):051:0> a.keys 
=> ["key1", "key2"] 
irb(main):052:0> a.keys.find_all{|k| a[k].include?('attr2_b')} 
=> ["key2"] 

이, 다른 포스터처럼 자신의 클래스를 사용하면 모듈을 만들고 대신

0

위의 다소-지저분한 find_all 문자열의 a.key_containing('attr2_b') 같은 일부에서 검색을 할 수있는 방법을 만들 수 있습니다 제안 및 관련 수업에 포함 시키십시오.

module MapHandeling 
    def [] key; @map ||= {}; @map[key] end 
    def []= key, value; @map ||= {}; @map[key] = value end 
    def index key; @map ||= {}; @map.index(key) end 
end 

또는

module MapHandeling 
    def initialize map; @map = map end 
    def [] key; @map[key] end 
    def []= key, value; @map[key] = value end 
    def index key; @map.index(key) end 
end 

클래스 A; https://github.com/josh/multimap을 : MapHandeling이 Multimap과 밖으로 시도

a = A.new(some_hash) 
a[:key1] = :attr1 
a[:key1] #=> :attr1 
a.index(:attr1) = :key1 
1

을 종료 등이 있습니다. 키마다 여러 개의 값을 가질 수 있으며 인덱스 작업이 가능합니다. 여기를 참조하십시오 (예 : https://github.com/josh/multimap/blob/master/lib/multimap.rb).

# call-seq: 
    # map.index(value) => key 
    # 
    # Returns the key for a given value. If not found, returns 
    # <tt>nil</tt>. 
    # 
    # map = Multimap["a" => 100, "b" => [200, 300]] 
    # map.index(100) #=> "a" 
    # map.index(200) #=> "b" 
    # map.index(999) #=> nil 
    def index(value) 
    invert[value] 
    end 
1

또 다른 방법 :

SET_OF_KEYS = [:key_1, :key_2, :key_3] 

Mapping = Struct.new(*SET_OF_KEYS) 
class Mapping 
    def index(value) 
    kv = self.each_pair.detect{|k,v| v == value } 
    kv.nil? ? nil : kv.first 
    end 
end 

mapping_1 = Mapping.new("attr_1_1", "attr_2_1", "attr_3_1") 
mapping_2 = Mapping.new("attr_1_2", "attr_2_2", "attr_3_2") 

p mapping_1[:key_1] #=> "attr_1_1" 
p mapping_1.index("attr_2_1") #=> :key_2 
p mapping_2[:key_3] #=> "attr_3_2" 
관련 문제