我有以下内容:
options = args.select{ |arg| arg.respond_to?(:keys) }.first.dup.keep_if {|k| filter_keys.include? k}
修改
options = args.select{ |arg| arg.respond_to?(:keys) }.first.select {|k| filter_keys.include? k}
first
有时会返回nil
,这会使dup
引发异常。因此,在调用first
之前,我希望以优雅的方式检查nil
是否返回dup
。
所以如果args
如下:
[{:collection=>["abe", "<mus>", "hest"], :include_blank=>true}]
和filter_keys如下:
filter_keys = %w(include_blank required)
结果将是:
{:include_blank=>true}
有时args会像:
[[["<Africa>", [["<South Africa>", "<sa>"], ["Somalia", "so"]]], ["Europe", [["Denmark", "dk"], ["Ireland", "ie"]]]]]
根本没有匹配。
或者可能喜欢:
[nil, {:collection=>["abe", "<mus>", "hest"], :prompt=>true, :include_blank=>true, :multiple => 'ss'}]
也给出了
{:include_blank=>true}
我对此的审判如下:
if f = args.select{ |arg| arg.respond_to?(:keys) }.first
options = f.select {|k| filter_keys.include? k}
end
此代码应该过滤args
数组,以便只从其中的任何哈希中获取匹配的键。
但是我没有看到这个代码简单而优雅,因为它分配了一个新的变量。
答案 0 :(得分:1)
首先,我认为args.select{ |arg| arg.respond_to?(:keys) }.first
可以写成args.detect{ |arg| arg.respond_to?(:keys) }
。
我喜欢这样
arg = args.detect{|arg| arg.respond_to?(:keys) }
options = arg.select{|k| filter_keys.include? k} if arg
答案 1 :(得分:0)
你可以这样写:
args.detect { |arg| arg.is_a?(Hash) }.select { |k| filter_keys.include?(k.to_s) }
请记住k.to_s
,因为您提供了带字符串的过滤器键列表:
filter_keys = %w(include_blank required)
但你在args数组中有符号