Ruby哈希,多个键指向相同的值

时间:2013-04-09 22:51:47

标签: ruby

我正在寻找一种方法,我会说哈希中的同义词键。

我希望多个键指向相同的值,因此我可以通过任何这些键读取/写入值。

例如,它应该像那样工作(假设:foo和:bar是同义词)

hash[:foo] = "foo"
hash[:bar] = "bar"
puts hash[:foo] # => "bar"

更新1

让我补充一些细节。我需要这些同义词的主要原因,因为我从外部源接收密钥,我无法控制,但多个密钥实际上可以与相同的值相关联。

4 个答案:

答案 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»是一个反向散列,用于查找一个密钥,如果它的值已经存在。