Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 使用ruby以干燥的方式提取散列中的值_Arrays_Json_Ruby_Each - Fatal编程技术网

Arrays 使用ruby以干燥的方式提取散列中的值

Arrays 使用ruby以干燥的方式提取散列中的值,arrays,json,ruby,each,Arrays,Json,Ruby,Each,我的应用程序向不同的方法传递一个json_元素,该元素的键不同,有时为空 为了处理它,我一直在使用以下示例代码对提取进行硬编码: def act_on_ruby_tag(json_element) begin # logger.progname = __method__ logger.debug json_element code = json_element['CODE']['$'] unless js

我的应用程序向不同的方法传递一个
json_元素
,该元素的键不同,有时为空

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

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?
我想消除硬编码的值,但不太清楚如何

我开始思考如下:

keys = json_element.keys
keys.each do |k|
        set_key = k.downcase
        instance_variable_set("@" + set_key, json_element[k]['$']) unless json_element[k].nil?
      end 
然后在方法的其余部分使用
@code

我打算把它变成一种方法,然后替换所有这些硬编码的代码


但是我不完全确定这是否是一个好的路径。

从一个方法返回一个散列结构几乎总是比设置任意的实例变量要好的多,在这个方法中,您可以使用
{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文件中定义它,您可以出于配置目的读入它。这实际上取决于这些更改的频率,以及您对输入的不规则性有何期望。

这是一种更简洁的方法,可以实现原始代码的功能

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

在这些情况下,我需要知道一个先验知识,即键是“code、predicate、replace……等等”"? 这些每次都会改变……考虑提前知道是否有帮助……可能……我如何解析它——我可能能够在没有
$
工件的情况下创建它。这是一种将4个特定键提取到顶级变量中的方法,无需使用元编程。在ruby中,通常有很多方法可以做相同的事情,比如说,我意识到“$”实际上是一个使用Cobravsmongose gem的艺术品。但是…真正的问题是你在讨论什么……拔出键并检查是否有值而不出错。有时其中一个键没有值——它是空的。这就是为什么我选择了
nil?
复选框。空和
nil?
是两件不同的事情,请记住这一点。如果您只是在寻找可以导航到的内容,那么与
v
进行测试就足够了。最少的代码通常更容易调试。