2013-04-21 1 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에서 더 잘 수행 될 수 있습니다. –

+0

검색 결과에서 설정 한 배열입니다. Google ComboChart 용 데이터 배열을 미리 준비해야합니다. –

답변

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 (& : 첫 번째) .map do | date, rs | 값 = rs [0] .zip (* rs [1 .. -1]). drop (1) .map {| xs | xs.reduce (+)} [날짜 값] 한가지 더, 당신은 단지 2 첫 번째 열을 나누는 방법을 알고 .flatten 끝? –

+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 

참고.
저는 이것이 숙제라고 말하지는 않지만, 그렇다면 학생들을 위해 그것을 할 때 우리는 실제로 어떤 호의를 베풀지 않습니다. 맞습니까? 또한이 솔루션은 Google에서 즉시 색인을 생성하는 공개 사이트에 제공되며 세계에있는 상위 100 개 사이트에 속하므로 정확하게 교수 또는 학년에게 비밀이 아닙니다. 학교가 http://turnitin.com/과 같은 국가 데이터베이스를 사용한다면 어떨까요? 원한다면 공개 코드 스 니펫을 확인할 수 있다고 가정합니다. 그리고 마침내, 애호가들에 의해 SO에 게시 된 다소 잘 쓰여진 코드가 있습니다. 내가 일반적으로 저학년 인트로 코스의 원작을 통과 할 수있을 지 확신하지 못합니다. :-)

+0

빠른 답변을 위해서는 Thx가 날짜를 요약 한 것입니다. 또한 나는 날짜가 같은 것들을 요약하고 중복 된 날짜가없는 것들을 요약하지 않도록합니다. –

+0

감사합니다. 이 예제에서는 한 가지만 더 필요로합니다. 중복의 수로 중복이 발생하는 배열의 첫 번째 2 개 값과 배열을 나눕니다. 예 : 'code [ "02-04-2013", 200.0, 250.0, 130, 70, 0, 0]이 ' '코드를 줄 것이다 [ "2013년 2월 4일", 100.0, 125.0, 130, 70, 0, 0] ' –

+0

로저가 업데이트. – DigitalRoss

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

는이 같은 것을 필요 '코드 [ "2013년 1월 4일", 100.0, 110.0, 120, 0, 0, 0], [ "2013년 2월 4일", 200.0, 250.0, 130, 70, 0,0], [ "2013년 3월 4일", 100.0, 110.0, 120, 0, 0, 0], [ "2013년 10월 4일", 200.0, 250.0, 100, 100, 0, 0], [ "2013년 11월 4일", 100.0, 140.0, 0, 110, 0, 0], [ "2013년 12월 4일", 100.0, 140.0, 0, 120, 0, 0], [ "2013년 9월 4일 ", 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, 100]] 이제 중복되는 행의 2 열을 나눌 필요가 있습니다 –

+0

이 예제에서는 "02-04-2013"을 2로 나눈 200.0과 250.0이 될 것입니다. –

+0

@user2305252 –

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]]] 
관련 문제