2

我有

 [
   {:date => "2012-05", :post => 1}, 
   {:date => "2012-12", :post => 1}, 
   {:date => "2013-02", :post => 1}, 
   {:date => "2012-05", :online => 1}
 ]

我想得到:

[
  {:date => "2012-05", :post => 1, :online => 1}, 
  {:date => "2012-12", :post => 1 }, 
  {:date => "2013-02", :post => 1 }
]

任何人都知道如何应用 Ruby 哈希/数组方法来实现这一点?

4

5 回答 5

6
q.group_by { |x| x[:date] }.values.map { |e| e.reduce :merge }
于 2013-02-08T16:30:36.523 回答
3

功能方法:

items_by_date = items.group_by { |h| h[:date] }
result = items_by_date.map { |date, hs| hs.reduce(:merge) }
于 2013-02-08T16:30:09.690 回答
1

您可以通过injectand解决它detect

arr = [
        {:date => "2012-05", :post => 1}, 
        {:date => "2012-12", :post => 1}, 
        {:date => "2013-02", :post => 1}, 
        {:date => "2012-05", :online => 1}
      ]

arr.inject([]) do |new_array, a|

  # if there is an existing hash in the new array with the same date
  # merge the values
  #
  if existing = new_array.detect{ |b| a[:date] == b[:date] } 
    existing.merge!(a)
  else
    new_array << a
  end

  # always return the new array for new iteration
  #
  new_array
end
于 2013-02-08T16:21:32.330 回答
0

这是一种尝试:

a = {:date=>"2012-05", :post=>1}, {:date=>"2012-12", :post=>1}, {:date=>"2013-02", :post=>1}
b = {:date=>"2012-05", :online=>1}

ar = {}; [a, b].flatten.each do |k|
  c = k.first[1]; ar[c] ||= Array.new
  ar[c] << { k.to_a.last[0] => k.to_a.last[1] }
end

ar.map { |k,v| { k => v[1] ? v[0].merge(v[1]) : v[0] } }
于 2013-02-08T16:13:52.070 回答
0
hash = [
   {:date => "2012-05", :post => 1}, 
   {:date => "2012-12", :post => 1}, 
   {:date => "2013-02", :post => 1}, 
   {:date => "2012-05", :online => 1}
 ]

hash.group_by{ |h| h[:date] }.values.map{ |x| x.reduce(:merge) }
=> [{:date=>"2012-05", :post=>1, :online=>1},
    {:date=>"2012-12", :post=>1},
    {:date=>"2013-02", :post=>1}]
于 2013-02-08T16:36:30.780 回答