【问题标题】:Rails merging two arrays of hashes?Rails合并两个哈希数组?
【发布时间】:2011-12-20 11:41:00
【问题描述】:

我很难掌握合并两个哈希数组所需的逻辑,似乎我以不同的方式询问了 this question a while back,我还尝试了其他一些事情喜欢这里提供的答案:merging arrays of hashes

任何理解这一点的帮助都会对我很有帮助。

假设我有以下数组,这是方法本身的输出,所以你可以想象那些:timestamps 是Time 对象

[
  {:timestamp=>2011-12-19 00:00:00 UTC},
  {:timestamp=>2011-12-19 01:00:00 UTC},
  {:timestamp=>2011-12-19 02:00:00 UTC},
  {:timestamp=>2011-12-19 03:00:00 UTC},
  {:timestamp=>2011-12-19 04:00:00 UTC},
  {:timestamp=>2011-12-19 05:00:00 UTC}
]

然后是这样一个额外的数组,每个数组都有另一个值(但有时除了:count之外可能还有更多值)

[
  {:timestamp=>2011-12-19 02:00:00 UTC, :count=>5},
  {:timestamp=>2011-12-19 04:00:00 UTC, :count=>21}
]

结果如下:

[
  {:timestamp=>2011-12-19 00:00:00 UTC},
  {:timestamp=>2011-12-19 01:00:00 UTC},
  {:timestamp=>2011-12-19 02:00:00 UTC, :count=>5},
  {:timestamp=>2011-12-19 03:00:00 UTC},
  {:timestamp=>2011-12-19 04:00:00 UTC, :count=>21},
  {:timestamp=>2011-12-19 05:00:00 UTC}
]

再次感谢您的帮助,我不知道为什么我无法找出合适的设计模式。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    看起来您首先按时间戳分组,然后合并值:

    (a1+a2).group_by{|h| h[:timestamp]}.map{|k,v| v.reduce(:merge)}
    

    【讨论】:

    • 您可以删除最后一个块上的& 以获得更短的代码:v.reduce(:merge)
    【解决方案2】:
    a = [
      {:timestamp=>'2011-12-19 00:00:00 UTC'},
      {:timestamp=>'2011-12-19 01:00:00 UTC'},
      {:timestamp=>'2011-12-19 02:00:00 UTC'},
      {:timestamp=>'2011-12-19 03:00:00 UTC'},
      {:timestamp=>'2011-12-19 04:00:00 UTC'},
      {:timestamp=>'2011-12-19 05:00:00 UTC'}
    ]
    
    b = [
      {:timestamp=>'2011-12-19 02:00:00 UTC', :count=>5},
      {:timestamp=>'2011-12-19 04:00:00 UTC', :count=>21}
    ]
    
    result = a.inject([]) do |memo, v|
      if match = b.detect { |w| (w.to_a & v.to_a).any? }
        memo << match.merge(v)
      else
        memo << v
      end
    end
    
    p result
    

    【讨论】:

      【解决方案3】:

      由于您使用每个散列的:timestamp 属性作为其“键”,如果您将数组实际转换为以:timestamp 属性作为键的散列,则很容易:

      h1 = Hash[a1.map{|h| [h[:timestamp], h]}]
      h2 = Hash[a2.map{|h| [h[:timestamp], h]}]
      

      然后,您想要的只是简单地merge-ing 两个哈希(并摆脱添加的键):

      p h1.merge(h2).values
      # => [
      #  {:timestamp=>"2011-12-19 00:00:00 UTC"},
      #  {:timestamp=>"2011-12-19 01:00:00 UTC"},
      #  {:timestamp=>"2011-12-19 02:00:00 UTC", :count=>5},
      #  {:timestamp=>"2011-12-19 03:00:00 UTC"},
      #  {:timestamp=>"2011-12-19 04:00:00 UTC", :count=>21},
      #  {:timestamp=>"2011-12-19 05:00:00 UTC"}
      #]
      

      【讨论】:

        猜你喜欢
        • 2016-10-07
        • 2017-09-26
        • 2016-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-19
        • 1970-01-01
        相关资源
        最近更新 更多