2015-03-30 72 views
2

我有幾個不同長度的數組,每個數組都有一個2項數組。例如:如何求和幾個數組的相應元素?

[["12:00", 7.0], ["01:00", 3.3], ["02:00", 11.9], ["03:00", 56.5]] 

[["12:00", 44.3], ["01:00", 2.25], ["02:00", 2.44], ["03:00", 46.11], ["04:00", 8.9], ["05:00", 18.187]] 

我想通過循環,並添加每個陣列的對應元件,進入一個新的數組。輸出數組將是我們加在一起的最長陣列的長度。

所以兩個數組上述相加將輸出以下內容:

[["12:00", 51.3], ["01:00", 5.55], ["02:00", 14.34], ["03:00", 102.61], ["04:00", 8.9], ["05:00", 18.187]] 

我不認爲我可以使用reduce()inject(),因爲我不想崩潰數組,也不是一個數組簡單的元素數組。

我真的不知道我該如何解決這個問題。

回答

4

你可以在一行Hash.merge。在合併過程中使用塊來合計值。

def sum_arrays(a, b) 
    Hash[a].merge(Hash[b]){|k, i, j| i + j}.to_a 
end 

輸出:

a = [["12:00", 7.0], ["01:00", 3.3], ["02:00", 11.9], ["03:00", 56.5]] 
b = [["12:00", 44.3], ["01:00", 2.25], ["02:00", 2.44], ["03:00", 46.11], ["04:00", 8.9], ["05:00", 18.187]]  
sum_arrays(a,b) 

=> [["12:00", 51.3], ["01:00", 5.55], ["02:00", 14.34], ["03:00", 102.61], ["04:00", 8.9], ["05:00", 18.187]] 

綜上所述兩個以上的陣列,增加一個行:

def sum_many_arrays(*a) 
    a.reduce{|s, i| sum_arrays(s, i)} 
end 

輸出:

sum_many_arrays([[:a,1],[:b,2]],[[:a,2],[:b,2],[:c,1]],[[:a,5],[:b,2]]) 
=> [[:a, 8], [:b, 6], [:c, 1]] 
+1

很好的回答,但我建議(因爲OP使用術語「幾個」),你將它概括爲'sum_arrays(arr)',其中'arr = [a,b,...]'。你可能不得不將'merge'改成'merge!'(又名'update')。此外,提供指向方法[Hash#merge](http://ruby-doc.org/core-2.2.0/Hash.html#method-i-merge)的鏈接並解釋您使用表單該方法使用塊來確定正在合併的兩個哈希中存在的鍵的值。 – 2015-03-30 23:51:17

+0

謝謝。多於兩個數組的更多行更新了答案。 – 2015-03-31 00:29:37

+1

很酷的使用哈希#合併和#to_a。 – Puhlze 2015-03-31 02:24:55

0

我建議@奧列格的做法,但總有另一種方式:

arr = [[["12:00", 7.0], ["01:00", 3.3], ["02:00", 11.9], ["03:00", 56.5]], 
     [["12:00", 44.3], ["01:00", 2.25], ["02:00", 2.44], ["03:00", 46.11], 
     ["04:00", 8.9]], 
     [["01:00", 22.25], ["02:00", 1.84], ["12:00", 13.3]]] 

keys = arr.reduce([]) { |keys,a| keys | a.map(&:first) } 
arr.map { |a| a.to_h.values_at(*keys) } 
    .transpose 
    .map { |e| [keys.shift, e.reduce(0) { |tot,x| tot + x.to_f }] } 
    #=> [["12:00", 64.6], ["01:00", 27.8], ["02:00", 16.18], 
    # ["03:00", 102.61], ["04:00", 8.9]] 

步驟:

keys = arr.reduce([]) { |keys,a| keys | a.map(&:first) } 
    #=> ["12:00", "01:00", "02:00", "03:00", "04:00"] 
b = arr.map { |a| a.to_h.values_at(*keys) } 
    #=> [[ 7.0, 3.3, 11.9, 56.5, nil], 
    # [44.3, 2.25, 2.44, 46.11, 8.9], 
    # [13.3, 22.25, 1.84, nil, nil]] 
c = b.transpose 
    #=> [[7.0, 44.3, 13.3], 
    # [3.3, 2.25, 22.25], 
    # [11.9, 2.44, 1.84], 
    # [56.5, 46.11, nil], 
    # [nil, 8.9, nil]] 
c.map { |e| [keys.shift, e.reduce(0) { |tot,x| tot + x.to_f }] } 
    #=> [["12:00", 64.6], ["01:00", 27.8], ["02:00", 16.18], 
    # ["03:00", 102.61], ["04:00", 8.9]] 

注意NilClass#to_f轉換nil0.0

要精心b上面的計算:

d = arr.map 
    #=> #<Enumerator: [[["12:00", 7.0], ["01:00", 3.3], ["02:00", 11.9], 
    #     ["03:00", 56.5]], 
    #     [["12:00", 44.3], ["01:00", 2.25], ["02:00", 2.44], 
    #     ["03:00", 46.11], ["04:00", 8.9]], 
    #     [["01:00", 22.25], ["02:00", 1.84], ["12:00", 13.3]]]:map> 

a = d.next 
    #=> [["12:00", 7.0], ["01:00", 3.3], ["02:00", 11.9], ["03:00", 56.5]] 
e = a.to_h 
    #=> {"12:00"=>7.0, "01:00"=>3.3, "02:00"=>11.9, "03:00"=>56.5} 
f = e.values_at(*keys) 
    #=> e.values_at(*["12:00", "01:00", "02:00", "03:00", "04:00"]) 
    #=> [7.0, 3.3, 11.9, 56.5, nil] 

a = d.next 
    #=> [["12:00", 44.3], ["01:00", 2.25], ["02:00", 2.44], 
    # ["03:00", 46.11], ["04:00", 8.9]] 
e = a.to_h 
    #=> {"12:00"=> 44.3, "01:00"=>2.25, "02:00"=>2.44, 
    # "03:00"=>46.11, "04:00"=> 8.9} 
f = e.values_at(*keys) 
    #=> [44.3, 2.25, 2.44, 46.11, 8.9] 

a = d.next 
    #=> [["01:00", 22.25], ["02:00", 1.84], ["12:00", 13.3]] 
e = a.to_h 
    #=> {"01:00"=>22.25, "02:00"=>1.84, "12:00"=>13.3} 
f = e.values_at(*keys) 
    #=> [13.3, 22.25, 1.84, nil, nil] 

c.map計算如下:

keys = ["12:00", "01:00", "02:00", "03:00", "04:00"] 

d = c.map 
    #=> #<Enumerator: [[ 7.0, 44.3, 13.3], [3.3, 2.25, 22.25], 
    #     [11.9, 2.44, 1.84], [56.5, 46.11, nil], 
    #     [nil, 8.9, nil]]:map> 

e = d.next 
    #=> [7.0, 44.3, 13.3] 
f = keys.shift 
    #=> "12:00" 
keys 
    #=> ["01:00", "02:00", "03:00", "04:00"] 
e.reduce(0) { |tot,x| tot + x.to_f } 
    #=> 64.6 

e = d.next 
    #=> [3.3, 2.25, 22.25] 
f = keys.shift 
    #=> "01:00" 
keys 
    #=> ["02:00", "03:00", "04:00"] 
e.reduce(0) { |tot,x| tot + x.to_f } 
    #=> 27.8 

e = d.next 
    #=> [11.9, 2.44, 1.84] 
f = keys.shift 
    #=> "02:00" 
keys 
    #=> ["03:00", "04:00"] 
e.reduce(0) { |tot,x| tot + x.to_f } 
    #=> 16.18 

e = d.next 
    #=> [56.5, 46.11, nil] 
f = keys.shift 
    #=> "03:00" 
keys 
    #=> ["04:00"] 
e.reduce(0) { |tot,x| tot + x.to_f } 
    #=> 102.61 

e = d.next 
    #=> [nil, 8.9, nil] 
f = keys.shift 
    #=> "04:00" 
keys 
    #=> [] 
e.reduce(0) { |tot,x| tot + x.to_f } 
    #=> 8.9 
相關問題