2013-04-21 48 views
0

我有一个包含这些类型数据的数组,并且我需要总结具有相同日期的列。如何在Ruby中对同一日期的列进行求和

[["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]] 

我该怎么做红宝石?我的意思是将同一日期的行整理成一行,如果没有重复的日期,请保留旧的。评论后

+0

这是从数据库中来吗?如果是这样,在ActiveRecord/SQL中可能会更好。 – 2013-04-21 20:48:22

+0

这是从搜索结果中设置的数组。我需要为Google ComboChart准备一系列数据。 – 2013-04-21 21:03:59

回答

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]]] 
+0

是的这就是我想要的! 我做了一些调整。 aggregated_rows = @ tmp.group_by(&:first).map do | date,rs | values = rs [0] .zip(* rs [1 ..- 1])。drop(1).map {| xs | xs.reduce(:+)} [日期,值] .flatten 结束 还有一件事,你知道如何划分只有2首列? – 2013-04-21 21:08:25

+0

我的意思是按日期的重复次数只分为2列。 – 2013-04-21 21:13:18

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个站点中,这对于教授或者分级者来说并不是秘密。如果学校使用像​​这样的国家数据库怎么办?我想他们可以检查公共代码片段,如果他们想。最后,还有一些相当精心编写的代码,发布在SO,由嗜好爱好者。如果我自己这样说,我不确定它通常可以通过低级别的入门课程原创作品。 :-)

+0

Thx为快速回答,事情也是这个总结日期。另外我要总结的日期是相同的,并保持没有没有重复日期的人。 – 2013-04-21 20:54:52

+0

感谢这个工作太棒了!在这个例子中,我需要另外一件事情,它将除以重复次数发生重复的前两个值和数组。 示例: 'code [“02-04-2013”​​,200.0,250。0,130,70,0,0]' 会给 '代码[ “2013年2月4日”,100.0,125.0,130,70,0,0]' – 2013-04-21 21:38:19

+0

罗杰,更新。 – DigitalRoss 2013-04-23 05:41:08

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]] 
+0

我需要这样的: 'code [[“”01-04-2013“,100.0,110.0,120,0,0,0”,[“02-04-2013”​​,200.0,250.0,130,70, 0,0],[“03-04-2013”​​,100.0,110.0,120,0,0,0],[“10-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-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]]' 现在我需要划分其被复制 – 2013-04-21 21:21:10

+0

那些行的2列在这个例子中,“02-04-2013”​​除以2将为200.0和250.0 – 2013-04-21 21:24:17

+0

@ user2305252不能得到你 – 2013-04-21 21:27:07

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]]] 
相关问题