我正在寻找一种方法,我会说哈希中的同义词键。
我希望多个键指向同一个值,所以我可以通过这些键中的任何一个读/写一个值。
例如,它应该像这样工作(假设 :foo 和 :bar 是同义词)
hash[:foo] = "foo"
hash[:bar] = "bar"
puts hash[:foo] # => "bar"
更新 1
让我补充几个细节。我需要这些同义词的主要原因是,我从外部源接收键,这是我无法控制的,但多个键实际上可以与相同的值相关联。
我正在寻找一种方法,我会说哈希中的同义词键。
我希望多个键指向同一个值,所以我可以通过这些键中的任何一个读/写一个值。
例如,它应该像这样工作(假设 :foo 和 :bar 是同义词)
hash[:foo] = "foo"
hash[:bar] = "bar"
puts hash[:foo] # => "bar"
更新 1
让我补充几个细节。我需要这些同义词的主要原因是,我从外部源接收键,这是我无法控制的,但多个键实际上可以与相同的值相关联。
根据您想要访问数据的方式,您可以通过将键或值设为数组来使它们成为同义词。无论哪种方式,您都需要做更多的工作来解析同义词而不是它们共享的定义词。
例如,您可以使用键作为同义词的定义。
# Create your synonyms.
hash = {}
hash['foo'] = %w[foo bar]
hash
# => {"foo"=>["foo", "bar"]}
# Update the "definition" of your synonyms.
hash['baz'] = hash.delete('foo')
hash
# => {"baz"=>["foo", "bar"]}
您也可以反转此结构,并将您的键数组改为同义词。例如:
hash = {["foo", "bar"]=>"foo"}
hash[hash.rassoc('foo').first] = 'baz'
=> {["foo", "bar"]=>"baz"}
您可以继承 hash 并覆盖[]
and []=
。
class AliasedHash < Hash
def initialize(*args)
super
@aliases = {}
end
def alias(from,to)
@aliases[from] = to
self
end
def [](key)
super(alias_of(key))
end
def []=(key,value)
super(alias_of(key), value)
end
private
def alias_of(key)
@aliases.fetch(key,key)
end
end
ah = AliasedHash.new.alias(:bar,:foo)
ah[:foo] = 123
ah[:bar] # => 123
ah[:bar] = 456
ah[:foo] # => 456
只要您将相同的对象分配给两个键,您可以做的事情是完全可能的。
variable_a = 'a'
hash = {foo: variable_a, bar: variable_a}
puts hash[:foo] #=> 'a'
hash[:bar].succ!
puts hash[:foo] #=> 'b'
这是有效的,因为hash[:foo]
和hash[:bar]
都引用了字母a
via的同一个实例variable_a
。但是,如果您使用分配,这将不起作用,hash = {foo: 'a', bar: 'a'}
因为在这种情况下:foo
并:bar
引用不同的实例变量。
你原来的帖子的答案是:
hash[:foo] = hash[:bar]
和
hash[:foo].__id__ == hash[:bar].__id__it
只要该值是参考值 (String, Array ...) ,它就会成立。
您的更新 1的答案可能是:
input.reduce({ :k => {}, :v => {} }) { |t, (k, v)|
t[:k][t[:v][v] || k] = v;
t[:v][v] = k;
t
}[:k]
其中 «input» 是输入数据的抽象枚举器(或数组),因为它来自 [key, value]+,«:k» 您的结果,«:v» 是用于查找键的反向哈希,如果它的价值已经存在。