1

我正在使用的Savon gem将返回单个对象或数组,在 SOAP 响应返回之前,我无法知道它会是哪个。

为方便起见,我希望将nil响应转换为[],将单个响应转换为 ,[obj]并将数组保留为数组。这可以通过 轻松完成Kernel#Array,因此:

> Array nil
=> [] 
> Array 1
=> [1] 
> Array [1,2,3]
=> [1, 2, 3] 

但是,因为Kernel#Array调用to_a,它会失败Hash覆盖to_a

> Array({a: 1})
=> [[:a, 1]]
> Array([{a: 1}, {b: 2}])
=> [{:a=>1}, {:b=>2}]

在上面的第 2 行我想看看[{:a=>1}]

4

5 回答 5

3

如果您使用 ActiveSupport,您可以执行以下操作:

> Array.wrap({a: 1})
=> [{:a, 1}]
> Array.wrap([{a: 1}, {b: 2}])
=> [{:a=>1}, {:b=>2}]
于 2012-07-24T22:46:03.587 回答
2
>> [nil].compact.flatten(1)
=> []
>> [1].compact.flatten(1)
=> [1]
>> [{a: 1, b: 2}].compact.flatten(1)
=> [{:a=>1, :b=>2}]
于 2012-07-24T23:02:23.427 回答
1

目前我可以Hash#to_a用我自己的straight_to_a方法绕过:

def straight_to_a(o)
  o.kind_of?(Array) ? o : [o].compact
end

因此:

> straight_to_a nil
=> [] 
> straight_to_a 1
=> [1] 
> straight_to_a( {a: 1} )
=> [{:a=>1}]

我希望有一个更简单的方法?

于 2012-07-24T16:00:52.587 回答
1

另一张海报建议使用主动支持。如果您不想只为一种方法向项目添加额外的依赖项,这里是 Active Support 的源代码Array.wrap

class Array
  def self.wrap(object)
    if object.nil?
      []
    elsif object.respond_to?(:to_ary)
      object.to_ary || [object]
    else
      [object]
    end
  end
end

您可以轻松地将此代码添加到您自己的utilities.rbcore_extensions.rb文件中,并将其包含在您的项目中。

于 2012-07-24T23:06:57.117 回答
0

您的解决方案似乎还可以,也许您可​​以尝试基于 的东西flatten,例如

def straight_to_a *ary
  ary.flatten(1)
end
于 2012-07-24T17:03:01.890 回答