Рассчитать промежуточную сумму нескольких значений в Ruby - PullRequest
2 голосов
/ 15 января 2020

Я пытаюсь сложить несколько значений, например

  • [4444.33, 0, 333.444, 0]
  • [3333.444, 0, 1123.44, 5444]
  • [321112.4, 443.3, 0, 4444]

Я думал обо всем oop, но я не знаю, как поступить:

values = []

(0..3).each do |value|
  # values << [4444.33, 0, 333.444, 0]       on 1st iteration
  # values << [3333.444, 0, 1123.44, 5444]   on 2nd iteration
  # values << [321112.4, 443.3, 0, 4444]     on 3rd iteration

  # Here I need to add each array with the next one
end

Результат будет [324890.174, 443.3, 1456.884, 9888]

Ответы [ 6 ]

3 голосов
/ 15 января 2020

Update1: это ничего не меняет. Вы все еще можете применить коды.

(0..3).each do |value|
  # First loop 
    values << [4444.33,0,333.444,0]
  # Second loop 
    values << [3333.444,0,1123.44,5444]
  # Third loop
    values << [321112.4,443.3,0,4444] 
  # Here I need to add each array with the next one
    values.transpose.map {|x| x.reduce(0, :+)}
end

1-й ответ: используйте отображение . только одна строка.

values.transpose.map {|x| x.reduce(0, :+)}
2 голосов
/ 15 января 2020

Поскольку у вас есть постоянная длина подмассивов в исходном массиве, вы можете использовать Array # Transpose и затем суммировать каждый результирующий массив.

Для Rails

values.transpose.map(&:sum)

Или, просто ruby, если вы используете версию ruby старше 2,4 (спасибо Себастьяну Пальме)

values.transpose.map {|x| x.inject(:+) }
1 голос
/ 15 января 2020

Я хочу добавить первый элемент первого массива и первый элемент второго массива таким же образом для всех четырех наборов [...], как итоговая сумма

К получить промежуточную сумму, вы можете начать с создания пустого массива «итогов» правильного размера:

totals = [0, 0, 0, 0]

Добавление строки означает добавление каждого из значений строки к соответствующему итогу.

Это можно сделать разными способами, например, вручную:

row = [4444.33, 0, 333.444, 0]

totals[0] += row[0]
totals[1] += row[1]
totals[2] += row[2]
totals[3] += row[3]

p totals #=> [4444.33, 0, 333.444, 0]

или через each_with_index в строке:

row = [3333.444, 0, 1123.44, 5444]

row.each_with_index { |v, i| totals[i] += v }

p totals #=> [7777.773999999999, 0, 1456.884, 5444]

или через map! (обратите внимание на !) и with_index в массиве totals:

row = [321112.4, 443.3, 0, 4444]

totals.map!.with_index { |t, i| t + row[i] }

p totals #=> [328890.174, 443.3, 1456.884, 9888]
0 голосов
/ 15 января 2020

Мои два цента используют Array # zip , просто если они уже сохранены в переменных:

a = [4444.33, 0, 333.444, 0]
b = [3333.444, 0, 1123.44, 5444]
c = [321112.4, 443.3, 0, 4444]

a.zip(b, c).map &:sum
#=> [324890.174, 443.3, 1456.884, 9888]

В противном случае:

values = [a, b, c]
values.inject([0,0,0,0]) { |acc, e| acc.zip(e).map &:sum }

Но транспонировать затем карту Подвести итог - более чистый способ.

0 голосов
/ 15 января 2020

Вы можете умножить свой вектор-строку на массив, преобразованный в матрицу, а затем преобразовать результат обратно в массив сумм.

values = [
  [  4444.33,    0,    333.444,    0],
  [  3333.444,   0,   1123.44,  5444],
  [321112.4,   443.3,    0,     4444]
]

require 'matrix'

(Matrix.row_vector([1]*values.size) * Matrix[*values]).to_a.flatten
 => [328890.174, 443.3, 1456.884, 9888] 

См. Матрица :: [] и Матрица :: row_vector .

Примечание:

a = Matrix.row_vector([1]*values.size)
  #=> Matrix[[1, 1, 1]] 
b = Matrix[*values]
  #=> Matrix[[4444.33, 0, 333.444, 0],
  #          [3333.444, 0, 1123.44, 5444],
  #          [321112.4, 443.3, 0, 4444]] 
a*b
  #=> Matrix[[328890.174, 443.3, 1456.884, 9888]] 
0 голосов
/ 15 января 2020

1-й ОТВЕТ:

values.transpose.map(&:sum)

ОБНОВЛЕНИЕ

values.map.with_index {|v, i| i > 1 ? [*v, values.dig(0, 0), values.dig(1, 0)] : v}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...