什么是优雅的 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 || {}
?
因此,如果要分配的 value
是 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 || {}
?
因此,如果要分配的 value
是 nil
,则该键的值变为 {}
。