【问题标题】:Ruby - Merge 2 arrays of objects and group by one attribute and sum the restRuby - 合并 2 个对象数组并按一个属性分组,然后将其余部分相加
【发布时间】:2012-12-10 20:49:10
【问题描述】:

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

数组 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>

【问题讨论】:

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


    【解决方案1】:

    我最终做了什么……需要测试以确保它按预期工作。

    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
    

    【讨论】:

      【解决方案2】:

      具体任务,但我尝试写一些代码。 首先,在 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
      

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

      【讨论】:

        猜你喜欢
        • 2023-02-07
        • 1970-01-01
        • 2018-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多