2012-07-24 55 views
1

Savon gem我使用的是给我回一个对象或数组哈希#,我也没有办法知道它会到SOAP响应回来。转换红宝石散列成阵列,而无需调用`to_a`

为方便起见,我希望将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}]

回答

2
>> [nil].compact.flatten(1) 
=> [] 
>> [1].compact.flatten(1) 
=> [1] 
>> [{a: 1, b: 2}].compact.flatten(1) 
=> [{:a=>1, :b=>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}] 

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

0

您的解决方案似乎确定,也许你如果你正在使用的ActiveSupport可以尝试基于flatten的东西,像

def straight_to_a *ary 
    ary.flatten(1) 
end 
3

,你可以做到以下几点:

> Array.wrap({a: 1}) 
=> [{:a, 1}] 
> Array.wrap([{a: 1}, {b: 2}]) 
=> [{:a=>1}, {:b=>2}] 
+0

接受现在,除非有人能想出不需要的ActiveSupport同样优雅的解决方案。 – dukedave 2012-07-24 22:51:12

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文件包括在你的项目中。