2015-04-14 5 views
-1

У меня есть массив из массива со строкой и 2 ИНТ так:Рубин, граф внутри массива

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

я во-первых, нужно объединить несколько вхождение этих массива на основе строки и накапливают значения обр [1] и обр [2]

Так что для этого Exemple мне это нужно:

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

Затем разделить эти оба значения, как, что:

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

Тогда сортировать их по убыванию.

Как я могу это сделать?

+0

В последней матрице показано, вы имеете в виду, чтобы написать '[«U26»,«ул ", 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, так each проходит в следующем значении enum0 и аналогичные расчеты выполняются:

(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

Спасибо, это работает как шарм –

Смежные вопросы