hash.each中的附加检查

时间:2018-01-17 17:00:00

标签: ruby

我有一个代码:

c = "SMTHLKKK"
b = {
  "lol1" => {
     "lol21" => {"lol3" => "smth"},
     "lol22" => {"lol3" => "smth"},
     "lol2" => {"lol3" => "smth"}
  }
}

我想检查c是否存在,如果存在,我想在"lol3"b的嵌套哈希中设置"SMTHLKKK"的值。否则,我将其设置为"SMT"。我想在设置值之前检查每个块中是否key != "lol22

我试过了:

b["lol1"].each{|key, value| value["lol3"] = c ? c : "SMT"}

我该如何检查?

1 个答案:

答案 0 :(得分:2)

你应该转向编写封装此类事物的方法,而不仅仅是将一些代码放在一起。它有助于更​​好地整理事物并更清楚地表达您的意图。例如:

require 'set'

DEFAULT_DEFAULT = 'SMT'

def fill_with_defaults(hash, default = nil, skip_keys = nil)
  default ||= DEFAULT_DEFAULT
  skip_keys ||= Set.new(skip_keys || [ ])

  hash.each do |key, sub|
    next if (skip_keys.include?(key))

    sub['lol3'] = default
  end

  hash
end

这里有一个名为fill_with_defaults的明确定义的方法,它接受三个参数,哈希,默认设置和要跳过的键。

如果未指定默认值并且为了性能原因将跳过的键转换为Set,则会为默认值分配默认值,这有助于更大的数组。如果你在较小的哈希上更频繁地调用它而不是在更大的哈希上更少次地调用它,你甚至可以强制该参数成为一个集合。在两个方向都有权衡。

该集合允许您快速跳过任何不必要的密钥,默认设置为一次以避免重复||检查。

然后你可以像这样使用它:

fill_with_defaults(b['lol1'], 'SMTHLKK', %w[ lol2 ])

这会跳过lol2键。