我正在寻找一种方法,我会说哈希中的同义词键。
我希望多个键指向相同的值,因此我可以通过任何这些键读取/写入值。
例如,它应该像那样工作(假设:foo和:bar是同义词)
hash[:foo] = "foo"
hash[:bar] = "bar"
puts hash[:foo] # => "bar"
更新1
让我补充一些细节。我需要这些同义词的主要原因,因为我从外部源接收密钥,我无法控制,但多个密钥实际上可以与相同的值相关联。
答案 0 :(得分:9)
根据您希望如何访问数据,您可以通过将键或值设为数组来使其成为同义词。无论哪种方式,您都需要做更多的工作来解析同义词而不是他们共享的定义词。
例如,您可以使用这些键作为同义词的定义。
# 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"}
答案 1 :(得分:4)
您可以对哈希进行子类化并覆盖[]
和[]=
。
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
答案 2 :(得分:1)
只要为两个键指定相同的对象,就可以完成所有操作。
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
引用了字母variable_a
的相同实例。但是,如果您使用了作业hash = {foo: 'a', bar: 'a'}
,则无效,因为在这种情况下:foo
和:bar
会引用不同的实例变量。
答案 3 :(得分:1)
原帖的答案是:
hash[:foo] = hash[:bar]
和
hash[:foo].__id__ == hash[:bar].__id__it
只要值是参考值(String,Array ...),将保持为true。
更新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»是一个反向散列,用于查找一个密钥,如果它的值已经存在。