我正在尝试从条件语句
构建哈希def create_hash(opt ={})
hash = {:a => if opt[:a] ? a : 0.40; end},
:b => if opt[:b] ? b : 0.30; end,
:c => if opt[:c] ? c : 0.05; end}
end
create_hash :a => 0.30
#hash = {:a => 0.30, :b => 0.30, :c => 0.05}
我尝试过使用tap,但似乎只有在满足条件而不是返回其他值时才会返回一个值 - Building a hash in a conditional way。有没有一种很好的方法来创建像这样的条件哈希?
答案 0 :(得分:4)
我会使用"or equals" operator:||=
def create_hash(opt = {})
hash = opt.dup
hash[:a] ||= 0.40
hash[:b] ||= 0.30
hash[:c] ||= 0.05
hash
end
答案 1 :(得分:4)
merge
简洁明了:
def create_hash(opt ={})
{
a: 0.40,
b: 0.30,
c: 0.05
}.merge(opt)
end
create_hash :a => 0.30
# => {:a=>0.3, :b=>0.3, :c=>0.05}
我们在一些内部代码中使用merge
来微调配置数据。我们有一个全局的YAML文件,如果我们需要为特定的应用程序或主机指定不同的东西,我们有一些小的YAML文件,只包含我们需要修改的哈希数据。我们将较小的哈希与全局哈希合并,并仅覆盖需要更改的数据。
看看你在做什么:
hash = {:a => if opt[:a] ? a : 0.40; end},
:b => if opt[:b] ? b : 0.30; end,
:c => if opt[:c] ? c : 0.05; end}
关于Ruby的工作原理存在很多困惑。您将立即遇到语法错误:
opt = {}
hash = {:a => if opt[:a] ? a : 0.40; end},
:b => if opt[:b] ? b : 0.30; end,
:c => if opt[:c] ? c : 0.05; end}
# =>
# ~> -:3: syntax error, unexpected =>, expecting end-of-input
# ~> :b => if opt[:b] ? b : 0.30; end,
# ~> ^
那是因为你不能:
},
结束第一行,终止哈希构造。清理缩进并移除if
和end;...
:
opt = {}
hash = {
:a => opt[:a] ? a : 0.40,
:b => opt[:b] ? b : 0.30,
:c => opt[:c] ? c : 0.05
}
# => {:a=>0.4, :b=>0.3, :c=>0.05}
它起作用了,但它仍然有代码味道,因为很难看出因为三元组而真正发生了什么("?:&#34 ;)声明。三元语句本身并不是邪恶的,但它们可能更难以阅读,因此请谨慎使用它们,并始终意识到它们会影响代码的清晰度。
答案 2 :(得分:2)
试试这个:
def create_hash(opt = {})
hash = Hash.new
hash[:a] = opt[:a] || 0.4
hash[:b] = opt[:b] || 0.3
hash[:c] = opt[:c] || 0.05
hash
end
答案 3 :(得分:0)
我更喜欢@ theTinMan使用merge
,但这可能会让一些读者熟悉一种不熟悉的方法。
def create_hash(opt = {})
hash = { a: 0.40, b: 0.30, c: 0.05 }
opt.default_proc = proc { |h, k| h[k] = hash[k] }
opt.values_at *hash.keys
opt
end
create_hash :a => 0.30
#=> {:a=>0.3, :b=>0.3, :c=>0.05}
create_hash
#=> {:a=>0.4, :b=>0.3, :c=>0.05}
opt.values_at *hash.keys
是在hash
但不在opt
中创建密钥的众多方法之一。