我有一个对象(从和API返回),它是散列或散列数组。如果它不是一个数组,我想把它包含在一个数组中。
我尝试在其上应用Array
,它以预期的方式运行数字或数组:
Array(1) # => [1]
Array([1, 2]) # => [1, 2]
Array([{a: 1}, {b: 2}]) # => [{:a=>1}, {:b=>2}]
但是哈希失败了:
Array({a: 1}) # => [[:a, 1]]
应为[{:a=>1}]
。
或者,我可以添加一个类型检查:
responses = [responses] if responses.is_a?(Hash)
有更好的解决方案吗?
答案 0 :(得分:2)
正如@mudasobwa所说,[responses].flatten
可能是最干净的解决方案:
[{a: 1}].flatten #=> [{:a=>1}]
[[{a: 1}, {b: 2}]].flatten #=> [{:a=>1}, {:b=>2}]
显然,这种不一致的响应格式不是一个很好的API设计;但不幸的是,与外部资源合作的本质......
如果上面数组中的每个哈希确实表示一个唯一的对象,那么我将保留该代码。但是,如果您对单个实体的每个属性实际使用不同的哈希值(?!),那么您可以按如下方式进一步清理API响应:
[{a: 1}].flatten.reduce(:merge) #=> {:a=>1}
[[{a: 1}, {b: 2}]].flatten.reduce(:merge) #=> {:a=>1, :b=>2}
答案 1 :(得分:2)
ActiveSupport
引入了Array#wrap
,它完全符合您的要求:
Array.wrap(responses)
我个人更喜欢从不使用任何Rails助手,原因很多,所以我会坚持使用[responses].flatten
,或者更好地使用最明确的版本:
case responses
when Hash then [responses]
when Array then responses
else raise "shit happened"
end
答案 2 :(得分:1)
如果它不是一个数组,我想将它括在一个数组中。
怎么样:
result = [result] unless result.is_a? Array
或者,使用try_convert
:
result = Array.try_convert(result) || [result]