我使用的Savon gem给了我一个对象或一个数组,在SOAP响应回来之前我无法知道它将会是什么。
为方便起见,我希望将nil
响应转换为[]
,将单个响应转换为[obj]
,并将数组保留为数组。这可以通过Kernel#Array
轻松完成,因此:
> Array nil
=> []
> Array 1
=> [1]
> Array [1,2,3]
=> [1, 2, 3]
但是,由于Kernel#Array
调用了to_a
,因此Hash
which overrides to_a
失败了:
> Array({a: 1})
=> [[:a, 1]]
> Array([{a: 1}, {b: 2}])
=> [{:a=>1}, {:b=>2}]
在上面的第2行,我希望看到[{:a=>1}]
。
答案 0 :(得分:3)
如果您使用的是ActiveSupport,则可以执行以下操作:
> Array.wrap({a: 1})
=> [{:a, 1}]
> Array.wrap([{a: 1}, {b: 2}])
=> [{:a=>1}, {:b=>2}]
答案 1 :(得分:2)
>> [nil].compact.flatten(1)
=> []
>> [1].compact.flatten(1)
=> [1]
>> [{a: 1, b: 2}].compact.flatten(1)
=> [{:a=>1, :b=>2}]
答案 2 :(得分: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}]
我希望有一种更简单的方法吗?
答案 3 :(得分:1)
另一张海报建议使用Active Support。如果您不想仅为一个方法为项目添加额外的依赖项,请参阅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.rb
或core_extensions.rb
文件中,并将其包含在您的项目中。
答案 4 :(得分:0)
您的解决方案似乎没问题,也许您可以尝试基于flatten
的内容,例如
def straight_to_a *ary
ary.flatten(1)
end