2

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

我希望多个键指向同一个值,所以我可以通过这些键中的任何一个读/写一个值。

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

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

更新 1

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

4

4 回答 4

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"}
于 2013-04-09T23:48:47.377 回答
5

您可以继承 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
于 2013-04-09T23:24:23.033 回答
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]都引用了字母avia的同一个实例variable_a。但是,如果您使用分配,这将不起作用,hash = {foo: 'a', bar: 'a'}因为在这种情况下:foo:bar引用不同的实例变量。

于 2013-04-09T23:13:32.253 回答
1

你原来的帖子的答案是:

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» 是用于查找键的反向哈希,如果它的价值已经存在。

于 2014-10-17T01:34:51.210 回答