惯用Ruby - 仅在不使用`if`的情况下分配变量

时间:2016-05-12 21:25:58

标签: ruby

我有很多像这样的行

api_data[:foo] = foo if foo
api_data[:bar] = bar if bar
api_data[:batz] = batz if batz

我想要一种简洁,惯用的方式,只分配!nil。

由于

5 个答案:

答案 0 :(得分:3)

如果您只想分配非nil的值:

api_data.merge!(
  {
    foo: foo,
    bar: bar,
    bart: barts
  }.reject { |_,v|v.nil? }
)

这有点乱,所以您可能想要对忽略nil作业的Hash类进行扩展:

class PickyHash < Hash
  def []=(k,v)
    return if (v.nil?)
    super
  end
end

然后:

api_data = PickyHash.new
api_data[:foo] = 'foo'
api_data[:foo] = nil

api_data
#> {:foo=>"foo"}

答案 1 :(得分:1)

api_data[:foo] = foo
api_data[:bar] = bar
api_data[:batz] = batz

api_data.reject! { |_, value| value.nil? }

会做到这一点。

答案 2 :(得分:0)

不能说我喜欢这个解决方案,但无论如何:

Hash[[:foo, :bar, :baz].find_all { |var| eval var.to_s }.map { |var| [var, eval(var.to_s)] }]

答案 3 :(得分:0)

您可以执行以下操作:

["foo", "bar", "batz"].each do |v|
    eval(v).tap {|val| api_data[v.to_sym] = val if val }
end

答案 4 :(得分:-1)

以下是使用Array#compactEnumerable#each_with_object

的内容
[foo, bar, batz].compact.each_with_object(api_data) {|elem, acc| acc.merge!({elem => elem})}

其中[foo, bar, batz].compact返回消除nil的输入数组,并且您将输入数组中的每个非nil元素合并为api_data散列作为初始值传递给each_with_object 1}}。