2015-04-14 73 views
-1

我有陣列的一個字符串數組和2 INT那樣:紅寶石,計數陣列內

[["u31", 12, 23], ["u26", 12, 23], ["u26", 11, 3]] 

我首先需要合併這些陣列基於所述字符串的多個發生和累積ARR的值[1]和ARR [2]

因此,對於本例,我需要這樣的:

[["u31", 12, 23], ["u26", 23, 26]] 

然後拆分那些這兩個值那樣:

[ 
    ["u31", "dl", 12], 
    ["u31", "ul", 23], 
    ["u26", "dl", 23], 
    ["u31", "ul", 26] 
] 

然後按降序排序。

我該怎麼做?

+0

在過去的矩陣顯示,你的意思寫的'[「U26」,「UL 「,26]'在最後一個數組中。 –

+0

@Menelk,我相信你是對的:一個不完整的剪切粘貼編輯。 –

回答

4

我會傾向於以不同的順序執行計算:

arr = [["u31", 12, 23], ["u26", 12, 23], ["u26", 11, 3]] 

arr.each_with_object({}) { |(s,*v),h| ['d1','ul'].zip(v).each { |t,x| 
     h.update([s,t]=>x) { |_,ox,nx| ox+nx } } }. 
    map { |(s,t),x| [s,t,x] }. 
    sort. 
    reverse 
    #=> [["u31", "ul", 23], 
    # ["u31", "d1", 12], 
    # ["u26", "ul", 26], 
    # ["u26", "d1", 23]] 

讓我們來看看這裏發生了什麼。

enum0 = arr.each_with_object({}) 
    #=> #<Enumerator: [["u31", 12, 23], ["u26", 12, 23], 
    #     ["u26", 11, 3]]:each_with_object({})> 

我們可以枚舉轉換爲數組看什麼值將由each被傳遞到塊:

enum0.to_a 
    #=> [[["u31", 12, 23], {}], [["u26", 12, 23], {}], 
    # [["u26", 11, 3], {}]] 

我們可以使用Enumerator#next獲得枚舉的每個值和手動分配它該塊變量:

(s,*v),h = enum0.next 
    #=> [["u31", 12, 23], {}] 
s #=> "u31" 
v #=> [12, 23] 
h #=> {} 

注意我是如何分解或「消歧」傳遞到塊陣列,這樣我就不必在塊內拆開它。

a = ['d1','ul'].zip(v) 
    #=> [["d1", 12], ["ul", 23]] 

上來:另一個枚舉:

enum1 = a.each 
    #=> #<Enumerator: [["d1", 12], ["ul", 23]]:each> 
t,x = enum1.next 
    #=> ["d1", 12] 
h.update([s,t]=>x) 
    #=> {}.update(["u31,"d1"]=>12) 
    #=> {["u31", "d1"]=>12} 

Hash#update(又名merge!)具有被構建了用來決定存在於兩者的散列密鑰的值的塊(h)和散列被合併({["u31", "d1"]=>12})。由於h爲空,因此該塊不用於第一次合併。

接下來,

t,x = enum1.next 
    #=> ["ul", 23] 
h.update([s,t]=>x) 
    #=> {["u31", "d1"]=>12}.update(["u31", "ul"]=>23) 
    #=> {["u31", "d1"]=>12, ["u31", "ul"]=>23} 

其中update返回h新值。我們已完成enum1,所以在enum0和類似的計算下一個值each通行證進行:

(s,*v),h = enum0.next 
    #=> [["u26", 12, 23], {["u31", "d1"]=>12, ["u31", "ul"]=>23}] 
['d1','ul'].zip(v).each { |t,x| h.update([s,t]=>x) {|_,ox,nx| ox+nx }} 
    #=> [["d1", 12], ["ul", 23]] 
h #=> {["u31", "d1"]=>12, ["u31", "ul"]=>23, ["u26", "d1"]=>12, 
    # ["u26", "ul"]=>23} 

我們現在通過的enum0第三和最後一個值成塊。同樣,計算是一樣的,除了update步:

(s,*v),h = enum0.next 
    #=> [["u26", 11, 3], 
    # {["u31", "d1"]=>12, ["u31", "ul"]=>23, ["u26", "d1"]=>12, 
    #  ["u26", "ul"]=>23}] 
a = ['d1','ul'].zip(v) 
    #=> [["d1", 11], ["ul", 3]] 
enum1 = a.each 
    #=> #<Enumerator: [["d1", 11], ["ul", 3]]:each> 
t,x = enum1.next 
    #=> ["d1", 11] 
h.update([s,t]=>x) 
    #=> {["u31", "d1"]=>12, ["u31", "ul"]=>23, 
    # ["u26", "d1"]=>12, ["u26", "ul"]=>23}.update(["u26","d1"],11) 
    # h and the hash being merged both have the key ["u26", "d1"], 
    # so the merged value is determined by update's block: 
    #=> { |_,ox,nx| ox+nx } => 12+11 => 23 
    #=> {["u31", "d1"]=>12, ["u31", "ul"]=>23, 
    # ["u26", "d1"]=>11, ["u26", "ul"]=>23} 
t,x = enum1.next 
    #=> ["ul", 3] 
h.update([s,t]=>x) 
    #=> {["u31", "d1"]=>12, ["u31", "ul"]=>23, 
    # ["u26", "d1"]=>11, ["u26", "ul"]=>26} 

我們現在基本上是完成了。我們只是有這個哈希轉化爲所需形式的數組:

a = h.map { |(s,t),x| [s,t,x] } 
    #=> [["u31", "d1", 12], ["u31", "ul", 23], 
    # ["u26", "d1", 11], ["u26", "ul", 26]] 

和排序:

a.sort.reverse 
    #=> [["u31", "ul", 23], 
    # ["u31", "d1", 12], 
    # ["u26", "ul", 26], 
    # ["u26", "d1", 11]] 
+0

謝謝,它像一個魅力 –