Ruby - 合并2个对象数组并按一个属性分组,然后对其余属性求和

时间:2012-12-10 20:49:10

标签: ruby arrays ruby-on-rails-3

鉴于我有2个包含对象的数组。在这些对象上有一个datetime属性和一定数量的指标。我需要做的是合并两个数组并按日期时间对指标求和。

数组1:

#<ReadingsProvider::Reading:0x007fc52dd5a0a8 @start_date=2012-12-09 03:00:00 UTC, @item1=13, @item2=46, @item3=6, @item4=4, @item5=9, @item6=17, @item7=34>, 
#<ReadingsProvider::Reading:0x007fc52dbd54d0 @start_date=2012-12-09 04:00:00 UTC, @item1=43, @item2=90, @item3=7, @item4=4, @item5=9, @item6=17, @item7=34>, 

数组2

#<ReadingsProvider::Reading:0x007fc52db95f88 @start_date=2012-12-09 03:00:00 UTC, @item1=23, @item2=16, @item3=5, @item4=6, @item5=8, @item6=20, @item7=36>, 
#<ReadingsProvider::Reading:0x007fc52db591f0 @start_date=2012-12-09 04:00:00 UTC, @item1=76, @item2=12, @item3=6, @item4=5, @item5=10, @item6=17, @item7=33>

最终数组(假设我手工数学是正确的......)

#<ReadingsProvider::Reading:0x007fc52db95f88 @start_date=2012-12-09 03:00:00 UTC, @item1=36, @item2=62, @item3=11, @item4=10, @item5=17, @item6=37, @item7=70>, 
#<ReadingsProvider::Reading:0x007fc52db591f0 @start_date=2012-12-09 04:00:00 UTC, @item1=119, @item2=102, @item3=13, @item4=9, @item5=19, @item6=34, @item7=67>

2 个答案:

答案 0 :(得分:0)

我最终做的......需要测试以确保它按预期工作。

def merge_arrays(array1, array2)
  result = array1.concat(array2).group_by(&:start_date).map do |date, array|
    my_hash = {
      start_date: date,
      item1: array.map(&:item1).inject(:+),
      item2: array.map(&:item2).inject(:+),
      item3: array.map(&:item3).inject(:+),
      item4: array.map(&:item4).inject(:+),
      item5: array.map(&:item5).inject(:+),
      item6: array.map(&:item6).inject(:+),
      item7: array.map(&:item7).inject(:+)
    }
    ReadingsProvider::Reading.new(my_hash)
  end

  result
end

答案 1 :(得分:0)

具体任务,但我尝试编写一些代码。 首先,包括ReadingsProvider :: Reading

的方法
def concat_with(another)
  if @reading_start_date == another.instance_variable_get(:@reading_start_date)
    instance_variables.each do |var|
      if var.to_s.include?("item") && another_value = another.instance_variable_get(var)
        another.instance_variable_set(var, another_value + instance_variable_get(var))
      end
    end
  end
end

然后一般方法:

array1.map do |reading|
  array2.map do |another|
    reading.concat_with(another)
  end
end.flatten.compact

如果我知道更多,那么代码应该更优雅。这段代码看起来很难看。