检查第一个方法是否返回nil并应用另一种方法的优雅方法

时间:2015-08-20 14:09:33

标签: ruby-on-rails ruby ruby-on-rails-4

我有以下内容:

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数组,以便只从其中的任何哈希中获取匹配的键。

但是我没有看到这个代码简单而优雅,因为它分配了一个新的变量。

2 个答案:

答案 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数组中有符号