【问题标题】:Array method versus hashes数组方法与哈希
【发布时间】:2017-12-05 11:31:59
【问题描述】:

我有一个对象(从 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)

有没有更好的解决方案?

【问题讨论】:

  • [responses].flatten.
  • 另外ActiveSupport 介绍了Array#wrap,它完全符合您的要求。
  • @mudasobwa 完美,Array#wrap 是我的选择。
  • “散列或散列数组” – 是否有机会修复 API?

标签: arrays ruby activesupport


【解决方案1】:

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】:

    正如@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}
    

    【讨论】:

      【解决方案3】:

      如果它还不是一个数组,我想将它包含在一个数组中。

      怎么样:

      result = [result] unless result.is_a? Array
      

      或者,使用try_convert:

      result = Array.try_convert(result) || [result]
      

      【讨论】:

        猜你喜欢
        • 2014-05-12
        • 2017-03-14
        • 2013-07-20
        • 2014-12-23
        • 2018-06-14
        • 1970-01-01
        • 1970-01-01
        • 2011-05-27
        • 1970-01-01
        相关资源
        最近更新 更多