87

在 Ruby 中,可以使用 << 将值附加到现有数组:

a = []
a << "foo"

但是,您还可以将键/值对附加到现有哈希吗?

h = {}
h << :key "bar"

我知道你可以这样做:

h[:key] = ""
h[:key] << "bar"

但这不是我想要的。

谢谢。

4

6 回答 6

149

merge!

h = {}
h.merge!(key: "bar")
# => {:key=>"bar"}
于 2013-11-03T18:22:47.847 回答
94

由于散列本身不是有序的,因此没有附加的概念。然而,自 1.9 以来的 Ruby 哈希保持插入顺序。以下是添加新键/值对的方法。

最简单的解决方案是

h[:key] = "bar"

如果您想要一种方法,请使用store

h.store(:key, "bar")

如果您真的非常想使用“铲子”运算符 ( <<),它实际上是将哈希值作为数组附加,并且您必须指定键:

h[:key] << "bar"

以上仅在密钥存在时有效。要附加新键,您必须使用默认值初始化散列,您可以这样做:

h = Hash.new {|h, k| h[k] = ''}
h[:key] << "bar"

您可能很想对 Hash 进行猴子修补,以包含一个按您编写的方式工作的铲子运算符:

class Hash
  def <<(k,v)
    self.store(k,v)
  end
end

但是,这不会继承在其他上下文中应用于 shovel 运算符的“语法糖”:

h << :key, "bar" #doesn't work
h.<< :key, "bar" #works
于 2013-11-03T19:41:14.773 回答
27

不,我认为您不能附加键/值对。我知道的唯一最接近store的是使用该方法:

h = {}
h.store("key", "value")
于 2013-11-03T18:18:46.707 回答
3

也许你想要 Hash#merge ?

1.9.3p194 :015 > h={}
 => {} 
1.9.3p194 :016 > h.merge(:key => 'bar')
 => {:key=>"bar"} 
1.9.3p194 :017 > 

如果要更改数组,请使用merge!

1.9.3p194 :016 > h.merge!(:key => 'bar')
 => {:key=>"bar"} 
于 2013-11-03T18:22:40.597 回答
3

Similar as they are, merge! and store treat existing hashes differently depending on keynames, and will therefore affect your preference. Other than that from a syntax standpoint, merge!'s key: "value" syntax closely matches up against JavaScript and Python. I've always hated comma-separating key-value pairs, personally.

hash = {}
hash.merge!(key: "value")
hash.merge!(:key => "value")
puts hash

{:key=>"value"}

hash = {}
hash.store(:key, "value")
hash.store("key", "value")
puts hash

{:key=>"value", "key"=>"value"}

To get the shovel operator << working, I would advise using Mark Thomas's answer.

于 2017-04-13T01:11:47.993 回答
2

我必须做类似的事情,但我需要使用相同的键添加值。当我使用合并或更新时,我无法使用相同的键推送值。所以我不得不使用哈希数组。

    my_hash_static = {:header =>{:company => 'xx', :usercode => 'xx', :password => 'xx',
                      :type=> 'n:n', :msgheader => from}, :body=>[]}
    my_hash_dynamic = {:mp=>{:msg=>message, :no=>phones} }        
    my_hash_full = my_hash_static[:body].push my_hash_dynamic
于 2014-04-02T20:57:53.693 回答