使用ruby以DRY方式提取哈希值

时间:2017-04-24 04:28:57

标签: arrays json ruby each

我的应用程序传递给>ap的不同方法,这些方法的键不同,有时也是空的。

为了处理它,我使用以下示例代码对提取进行了硬编码:

<

我想消除硬编码的价值,并不太确定如何。

我开始思考如下:

json_element

然后在方法的其余部分使用def act_on_ruby_tag(json_element) begin # logger.progname = __method__ logger.debug json_element code = json_element['CODE']['$'] unless json_element['CODE'].nil? predicate = json_element['PREDICATE']['$'] unless json_element['PREDICATE'].nil? replace = json_element['REPLACE-KEY']['$'] unless json_element['REPLACE-KEY'].nil? hash = json_element['HASH']['$'] unless json_element['HASH'].nil?

我打算尝试转换为方法,然后替换所有这些硬编码的代码。

但我不完全确定这是否是一条好路。

2 个答案:

答案 0 :(得分:3)

从具有{ code: ... }之类的方法返回哈希结构而不是设置任意实例变量几乎总是更好。如果您将它们放回到一致的容器中,呼叫者可以更轻松地将其传送到正确的位置,将其存储以供日后使用,或选择他们想要的内容并丢弃其余的内容。

尝试用一系列更小,更轻的操作来打破一个大而笨重的步骤也是一个好主意。这使得代码更容易理解:

def extract(json)
  json.reject do |k, v|
    v.nil?
  end.map do |k, v|
    [ k.downcase, v['$'] ]
  end.to_h
end

然后你明白了:

extract(
  'TEST' => { '$' => 'value' },
  'CODE' => { '$' => 'code' },
  'NULL' => nil
)
# => {"test"=>"value", "code"=>"code"}

如果你想将整个事物作为一个实例变量来保留,那么这是一个相当典型的模式,但是它有一个可预测的名称,不受任何JSON文档的影响。重新消费。

另一种方法是将密钥硬编码为常量,如:

KEYS = %w[ CODE PREDICATE ... ]

然后使用它,或者更进一步,在YAML或JSON文件中定义您可以读入以进行配置。这实际上取决于这些变化的频率,以及您对输入的不规则性有何期望。

答案 1 :(得分:0)

这是一种稍微简洁的方式来完成原始代码的工作。

code, predicate, replace, hash = json_element.values_at *%w{
  CODE PREDICATE REPLACE-KEY HASH
}.map { |x| x.fetch("$", nil) if x }