在Ruby中,可以使用<<将值附加到现有数组中:
a = []
a << "foo"
但是,您还可以将键/值对附加到现有的哈希吗?
h = {}
h << :key "bar"
我知道你可以做:
h[:key] = ""
h[:key] << "bar"
但这不是我想要的。
谢谢。
Answers:
有merge!
。
h = {}
h.merge!(key: "bar")
# => {:key=>"bar"}
merge!
仅仅创建一个新的键/值对就符合资格,因为它实际上已用于其他目的。
store
只需添加一对新密钥,就不必关心密钥是否已存在。与merge!
然而,有重复键条目被覆盖所以这种方法并不仅仅是增加对位。如果对这两者进行基准测试,则会发现store
速度更快(但琐碎,但尤其是在较小的哈希值上)
Hash#merge!
返回接收方哈希值,就像Array#<<
返回接收方数组一样。Hash#store
是完全不同的事情。另外,key: "bar"
在参数位置使用哈希语法糖时,我认为这是最接近您的符号的方法。我知道这更接近您想要的。
由于哈希不是固有地排序的,因此没有附加的概念。从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
但是,这不会继承在其他情况下应用于铲子运算符的“语法糖”:
h << :key, "bar" #doesn't work
h.<< :key, "bar" #works
不,我认为您不能附加键/值对。我知道的唯一最接近的东西是使用store
方法:
h = {}
h.store("key", "value")
也许您想要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"}
merge
这是个好主意,因为它返回一个新数组。不将新对添加到现有哈希中。
merge!
(即到现有数组)而不是merge
?
merge!
从技术上讲,在这种情况下有效,但我认为应该将其用于合并两个哈希,而不是简单地添加一对新哈希。另外,如果您进行基准测试merge!
,它会比store
;;慢
与它们类似,merge!
并且根据键名store
对现有哈希进行不同的处理,因此将影响您的偏好。从语法的角度来看,merge!
的key: "value"
语法与JavaScript和Python紧密匹配。我一直以来都讨厌以逗号分隔键/值对。
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"}
为了使铲斗操作员<<
工作,我建议使用马克·托马斯的答案。
我必须做类似的事情,但是我需要使用相同的键添加值。使用合并或更新时,无法使用相同的键推送值。所以我不得不使用哈希数组。
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
h[:key] = "bar"
呢?