2015-07-11 7 views
2

Я работаю с несколькими массивами с одной строкой и целым числом. Мне удалось собрать дубликаты во вложенных массивах, поскольку я хочу их объединить. Так как я петлю над моим родительским массивом выводит это:Объединение массивов и целых чисел

[["word", 1, 1, 3, 4], ["word", 2, 1, 3, 4]] 

и другой пример:

[["without", 1, 1, 3, 4], ["without", 2, 1, 3, 4], ["without", 3, 1, 0, 0]] 

Я хочу, чтобы функция, чтобы объединить их в один массив и просуммировать целые числа. Таким образом, первым примером, приведенным выше, станет:

["word", 3, 2, 6, 8] 

Я пробовал много разных методов, таких как ввод и сокращение. Моя последняя попытка не самая элегантная:

# data is set of array 
def inject_array(data) 
    clicks = 0 
    imps = 0 
    cost = 0 
    converted_clicks = 0 
    data.each do |i| 
    clicks += i[1] 
    i[1] = clicks 
    imps += i[2] 
    i[2] = imps 
    cost += i[3] 
    i[3] = cost 
    converted_clicks += i[4] 
    i[4] = converted_clicks 
    end 

Это становится немного грязным, есть ли более чистый способ?

+0

Не уверен, что мне что-то не хватает, но не лучше ли отслеживать сумму, используя хэш? – NigoroJr

ответ

4

Предполагая, что массивы всегда будут такими же длинами, вы можете использовать Array#transpose перенести свой массив массивов из строки на основе массивов столбцов на основе:

[["word", 1, 1, 3, 4], ["word", 2, 1, 3, 4]].transpose 
=> [["word", "word"], [1, 2], [1, 1], [3, 3], [4, 4]] 

Оттуда, это достаточно тривиально, чтобы подвести числа в каждой:

[["word", 1, 1, 3, 4], ["word", 2, 1, 3, 4]].transpose.map.with_index do |e, i| 
    i == 0 ? e.first : e.inject(:+) 
end # => ["word", 3, 2, 6, 8] 
+0

Я предпочитаю этот путь, нежели перестраивать свою собственную переборку. – wurde

0

Вы можете также методы класса Matrix. Напомним, что суммировать каждый столбец матрицы с r строк, вы предварительно умножить матрицу на вектор-строку, состоящей из r1 S:

require 'matrix' 

a = [["word", 1, 1, 3, 4], ["word", 2, 1, 3, 4]] 

[a.first.first, (Matrix[[1]*a.size] * Matrix[*a.map { |e| e[1..-1] }]).to_a.first] 
    #=> ["word", [3, 2, 6, 8]] 
0

Один из способов заключается в петле над массивами, суммировать части, и перестраивать.

word_array = [['word', 1, 1, 3, 4], ['word', 2, 1, 3, 4]] 
puts "Squashing #{word_array}..." 
i1 = 0 
i2 = 0 
i3 = 0 
i4 = 0 
word_array.each do |arr| 
    i1 += arr[1] 
    i2 += arr[2] 
    i3 += arr[3] 
    i4 += arr[4] 
end 
puts ['word', i1, i2, i3, i4].inspect 
Смежные вопросы