散列合并与赋值

hash merge vs assignment

我有一个简单的例子,传递的散列缺少一个字段。

我想知道添加具有某些默认值的字段的首选方式是什么,选择一种方式是否比另一种方式有好处,什么时候选择?

hash['field'] = some_value

hash.merge!({ 'field' => some_value })

编辑:意味着使用合并!

第一种方法更改散列本身(不创建新对象)

第二个使用原始 hash{ 'field' => some_value } 的键创建 Hash class 的新实例(比较 hashobject_idhash 的结果hash.merge({ 'field' => some_value }) - 它们会有所不同)

选哪个? 这取决于 - 如果改变 hash 的状态对你来说不是问题,那么第一种方法就可以了。

首先,重要说明:Hash#merge returns 一个 new 对象,而 Hash#[]=Hash#merge! 改变 现有对象:

hash = {a: :b}

hash.merge(c: :d) # => {a: :b, c: :d}
puts hash # => {a: :b} (!!!)

hash[:c] = :d
puts hash # => {a: :b, c: :d}

hash.merge!(e: :f)
puts hash # => {a: :b, c: :d, e: :f}

Hash#[]= 上使用 Hash#merge! 的主要用例是(顾名思义!)当您有两个现有的散列需要合并在一起时:

hash1 = {a: :b, c: :d}
hash2 = {e: :f, g: :h}

hash1.merge!(hash2)
puts hash1 # => {a: :b, c: :d, e: :f, g: :h}

这等同于,但比循环遍历 hash2 中所有值的更冗长的方法更方便:

hash2.each do |key, value|
  hash1[key] = value
end

I'm wondering which is the preferred way of adding the field with some default

我会将默认值存储在一个额外的散列中(即使它只是一个值),这样我以后可以轻松添加其他值:

defaults = { foo: 1, bar: 2 }

然后,我将通过创建新哈希以保留给定值的方式合并默认值:

hash = { foo: 100, baz: 300 }
hash = defaults.merge(hash)
#=> {:foo=>100, :bar=>2, :baz=>300}

或通过就地更改哈希:

hash = { foo: 100, baz: 300 }
hash.merge!(defaults) { |key, given_value, default_value| given_value }
#=> {:foo=>100, :baz=>300, :bar=>2}