从条件语句构建哈希

时间:2014-11-30 21:00:10

标签: ruby hash conditional

我正在尝试从条件语句

构建哈希
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。有没有一种很好的方法来创建像这样的条件哈希?

4 个答案:

答案 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,
# ~>              ^

那是因为你不能:

  • 在哈希分配中使用尾随条件。
  • },结束第一行,终止哈希构造。

清理缩进并移除ifend;...

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中创建密钥的众多方法之一。