什么是优雅的 Ruby 方式来获得 'nil' 的条件?

What is an elegant Ruby way to have a condition of 'nil'?

有没有更优雅的方式来编写这段代码?

    def create_a_hash_from_a_collection
      my_hash = {}

      collection_of_hashes.each do |key, value|
        my_hash[key] = {} if my_hash[key].nil?
        my_hash[key] = value
      end

      my_hash
    end

我觉得笨拙的一行是这样的:

my_hash[key] = {} if my_hash[key].nil?

有shorthand表达方式吗?

我想你想要的是用默认值初始化你的 my_hash,这样你就不需要检查它是否为 nil。

这可以使用 Hash.new 构造函数来完成,比较:

my_hash = {}
puts my_hash['no_existing_key'] #=> nil

my_hash = Hash.new({})
puts my_hash['no_existing_key'] #=> {}

然后您可以将代码缩减为:

def create_a_hash_from_a_collection
  my_hash = Hash.new({})

  collection_of_hashes.each do |key, value|
    my_hash[key] = value
  end

  my_hash
end

您可以使用 ||= 运算符,它完全符合您的要求

my_hash[key] ||= {} 

我在这里的其余回答是因为我不确定 "collection of hashes" 是什么,所以我最好的猜测是它是一个哈希数组。如果我错了,请告诉我并忽略此答案的其余部分。

看来您的方法的其余部分可能无法完成您想要做的事情。考虑:

@collection_of_hashes = [{foo: 'bar'}, {baz: 'qux'}]

def create_a_hash_from_a_collection
   my_hash = {}
   @collection_of_hashes.each do |key, value|
     # this is not actually doing anything here and returns same with or
     # without the following line
     # my_hash[key] ||= {}
     my_hash[key] = value
   end

   my_hash
 end
#=> {{:foo=>"bar"}=>nil, {:baz=>"qux"}=>nil}

但你可能想要的是

def create_a_hash_from_a_collection
  my_hash = {}
  @collection_of_hashes.each do |hash|
    hash.keys.each do |k|
      my_hash[k] = hash[k]
    end
  end
  my_hash
end
#=> {:foo=>"bar", :baz=>"qux"}

但还要记住,如果我们倾向于假设的任何 "collection of hashes" 将是一个哈希数组,并且包含相同的密钥,那么哪个获胜?这段代码,它将是数组键值中的最后一项。您的方法的实际目标是什么?

如果您想为初始哈希中的每个键都使用一个全新的哈希,您需要使用一个块对其进行初始化:

hash = Hash.new { |hash, key| hash[key] = {} }

hash[:foo].object_id == hash[:bar].object_id #=> false

否则,如果你这样做,它将始终是相同的默认哈希值

hash = Hash.new({})
hash[:foo].object_id == hash[:bar].object_id #=> true

既然你要赋值,也许你可以使用 my_hash[key] = value || {}?

因此,如果要分配的 valuenil,则该键的值变为 {}