如何在Ruby中对具有相同日期的列求和

时间:2013-04-21 20:24:43

标签: arrays ruby sum

我有一个包含这些类型数据的数组,我需要总结相同日期的列。

[["01-04-2013", 100.0, 110.0, 120, 0, 0, 0], ["02-04-2013", 100.0, 110.0, 130, 0, 0, 0], ["03-04-2013", 100.0, 110.0, 120, 0, 0, 0], ["10-04-2013", 100.0, 110.0, 100, 0, 0, 0], ["02-04-2013", 100.0, 140.0, 0, 70, 0, 0], ["10-04-2013", 100.0, 140.0, 0, 100, 0, 0], ["11-04-2013", 100.0, 140.0, 0, 110, 0, 0], ["12-04-2013", 100.0, 140.0, 0, 120, 0, 0], ["09-04-2013", 0.0, 0.0, 0, 0, 130, 0], ["17-04-2013", 0.0, 0.0, 0, 0, 30, 0], ["15-04-2013", 100.0, 130.0, 0, 0, 0, 17], ["17-04-2013", 100.0, 130.0, 0, 0, 0, 90], ["18-04-2013", 100.0, 130.0, 0, 0, 0, 100]]

我怎样才能在红宝石中做到这一点?我的意思是将具有相同日期的行汇总到一行中,如果没有重复日期,请保留旧日期。

4 个答案:

答案 0 :(得分:2)

require 'pp'
require 'matrix'

d = [["01-04-2013", 100.0, 110.0, 120, 0, 0, 0], ["02-04-2013", 100.0, 110.0, 130, 0, 0, 0], ["03-04-2013", 100.0, 110.0, 120, 0, 0, 0], ["10-04-2013", 100.0, 110.0, 100, 0, 0, 0], ["02-04-2013", 100.0, 140.0, 0, 70, 0, 0], ["10-04-2013", 100.0, 140.0, 0, 100, 0, 0], ["11-04-2013", 100.0, 140.0, 0, 110, 0, 0], ["12-04-2013", 100.0, 140.0, 0, 120, 0, 0], ["09-04-2013", 0.0, 0.0, 0, 0, 130, 0], ["17-04-2013", 0.0, 0.0, 0, 0, 30, 0], ["15-04-2013", 100.0, 130.0, 0, 0, 0, 17], ["17-04-2013", 100.0, 130.0, 0, 0, 0, 90], ["18-04-2013", 100.0, 130.0, 0, 0, 0, 100]]

pp(
  d.group_by(&:first).values.reject do |v|
    v.size <= 1
  end.map do |e|
    e.inject do |m, e|
      (Vector.[](*m) + Vector.[](*e)).to_a
    end
  end
)

评论后更新:

  d.group_by(&:first).values.map do |e|
    e.inject do |m, e|
      [e[0], (Vector.[](*m[1..-1]) + Vector.[](*e[1..-1])).to_a].flatten
    end
  end.sort

规格变更提示:

def v m
  Vector.[](*m.drop(1))
end

d.group_by(&:first).values.map do |group|
  r = group.inject do |m, e|
    [e[0], *(v(m) + v(e)).to_a]
  end
  r[1] /= group.size
  r[2] /= group.size
  r
end.sort

注意。
我不是说这是作业,但在这种情况下,显而易见的是,当我们为学生做的时候,我们是不是真的对他们有任何好处,对吧?此外,这个解决方案是在一个公共网站上提供的,该网站立即被谷歌索引,并且位于世界上的前100个网站中,这对于教授或评分者来说并不完全是秘密。如果学校使用像http://turnitin.com/这样的国家数据库怎么办?我想如果他们愿意的话,他们可以查看公共代码片段。最后,有一些相当精心编写的代码,由嗜好,业余爱好者发布。我不确定它通常可以通过低级别的介绍性原创作品,如果我,哼哼,我自己这么说。 : - )功能

答案 1 :(得分:0)

require 'pp'

a = [["01-04-2013", 100.0, 110.0, 120, 0, 0, 0], ["02-04-2013", 100.0, 110.0, 130, 0, 0, 0], ["03-04-2013", 100.0, 110.0, 120, 0, 0, 0], ["10-04-2013", 100.0, 110.0, 100, 0, 0, 0], ["02-04-2013", 100.0, 140.0, 0, 70, 0, 0], ["10-04-2013", 100.0, 140.0, 0, 100, 0, 0], ["11-04-2013", 100.0, 140.0, 0, 110, 0, 0], ["12-04-2013", 100.0, 140.0, 0, 120, 0, 0], ["09-04-2013", 0.0, 0.0, 0, 0, 130, 0], ["17-04-2013", 0.0, 0.0, 0, 0, 30, 0], ["15-04-2013", 100.0, 130.0, 0, 0, 0, 17], ["17-04-2013", 100.0, 130.0, 0, 0, 0, 90], ["18-04-2013", 100.0, 130.0, 0, 0, 0, 100]]
h = {}
a.group_by(&:first).each{|k,v| v.flatten!.delete(k); h[k] = v.inject(:+)}
pp h

输出:

{"01-04-2013"=>330.0,
 "02-04-2013"=>650.0,
 "03-04-2013"=>330.0,
 "10-04-2013"=>650.0,
 "11-04-2013"=>350.0,
 "12-04-2013"=>360.0,
 "09-04-2013"=>130.0,
 "17-04-2013"=>350.0,
 "15-04-2013"=>247.0,
 "18-04-2013"=>330.0}

pp a.group_by(&:first).map{|k,v| v.flatten!.uniq!}

输出:

[["01-04-2013", 100.0, 110.0, 120, 0],
 ["02-04-2013", 100.0, 110.0, 130, 0, 140.0, 70],
 ["03-04-2013", 100.0, 110.0, 120, 0],
 ["10-04-2013", 100.0, 110.0, 100, 0, 140.0],
 ["11-04-2013", 100.0, 140.0, 0, 110],
 ["12-04-2013", 100.0, 140.0, 0, 120],
 ["09-04-2013", 0.0, 0, 130],
 ["17-04-2013", 0.0, 0, 30, 100.0, 130.0, 90],
 ["15-04-2013", 100.0, 130.0, 0, 17],
 ["18-04-2013", 100.0, 130.0, 0, 100]]

pp a.group_by(&:first).map{|k,v|  v.transpose.map!{|a| a.inject(:+)}}

输出:

[["01-04-2013", 100.0, 110.0, 120, 0, 0, 0],
 ["02-04-201302-04-2013", 200.0, 250.0, 130, 70, 0, 0],
 ["03-04-2013", 100.0, 110.0, 120, 0, 0, 0],
 ["10-04-201310-04-2013", 200.0, 250.0, 100, 100, 0, 0],
 ["11-04-2013", 100.0, 140.0, 0, 110, 0, 0],
 ["12-04-2013", 100.0, 140.0, 0, 120, 0, 0],
 ["09-04-2013", 0.0, 0.0, 0, 0, 130, 0],
 ["17-04-201317-04-2013", 100.0, 130.0, 0, 0, 30, 90],
 ["15-04-2013", 100.0, 130.0, 0, 0, 0, 17],
 ["18-04-2013", 100.0, 130.0, 0, 0, 0, 100]]

答案 2 :(得分:0)

aggregated_rows = rows.group_by(&:first).map do |date, rows_by_date|
  values = rows_by_date.transpose.drop(1).map { |xs| xs.reduce(:+) }
  [date, values]
end

#[["01-04-2013", [100.0, 110.0, 120, 0, 0, 0]],
# ["02-04-2013", [200.0, 250.0, 130, 70, 0, 0]],
...
# ["18-04-2013", [100.0, 130.0, 0, 0, 0, 100]]]

答案 3 :(得分:0)

a = [["01-04-2013", 100.0, 110.0, 120, 0, 0, 0], ["02-04-2013", 100.0, 110.0, 130, 0, 0, 0], ["03-04-2013", 100.0, 110.0, 120, 0, 0, 0], ["10-04-2013", 100.0, 110.0, 100, 0, 0, 0], ["02-04-2013", 100.0, 140.0, 0, 70, 0, 0], ["10-04-2013", 100.0, 140.0, 0, 100, 0, 0], ["11-04-2013", 100.0, 140.0, 0, 110, 0, 0], ["12-04-2013", 100.0, 140.0, 0, 120, 0, 0], ["09-04-2013", 0.0, 0.0, 0, 0, 130, 0], ["17-04-2013", 0.0, 0.0, 0, 0, 30, 0], ["15-04-2013", 100.0, 130.0, 0, 0, 0, 17], ["17-04-2013", 100.0, 130.0, 0, 0, 0, 90], ["18-04-2013", 100.0, 130.0, 0, 0, 0, 100]]

require "pp"

def group_and_sum_rows_by_date_string(a)
    # instantiate a hash that returns an empty array for a key
    # that doesn't exist
    h = Hash.new([])
    a.each do |row|
        # populate the hash with date string as key, and array of 
        # arrays of the values for that date string
        h[k=row.shift] = ([row] + h[k]).compact
    end
    # add up all the corresponding values in each element's array
    # arrays, and return the result as an array
    h.map{|k, v| [k, v.transpose.map{|x| x.inject(:+)}]}
end

pp group_and_sum_rows_by_date_string(a)

[["15-04-2013", [100.0, 130.0, 0, 0, 0, 17]],
 ["03-04-2013", [100.0, 110.0, 120, 0, 0, 0]],
 ["02-04-2013", [200.0, 250.0, 130, 70, 0, 0]],
 ["17-04-2013", [100.0, 130.0, 0, 0, 30, 90]],
 ["18-04-2013", [100.0, 130.0, 0, 0, 0, 100]],
 ["09-04-2013", [0.0, 0.0, 0, 0, 130, 0]],
 ["01-04-2013", [100.0, 110.0, 120, 0, 0, 0]],
 ["12-04-2013", [100.0, 140.0, 0, 120, 0, 0]],
 ["10-04-2013", [200.0, 250.0, 100, 100, 0, 0]],
 ["11-04-2013", [100.0, 140.0, 0, 110, 0, 0]]]