Как вычесть массивы целых - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть четыре массива типа int:

num_defect = [30, 30, 20, 20, 18, 18, 5, 5]
num_fixes = [1, 0, 3, 2, 1, 2, 2, 2]
num_blocks = [0, 0, 0, 0, 2, 2, 1, 0]
num_ext_defects = [1, 1, 0, 0, 2, 2, 2, 1]

Я хочу отобразить количество открытых дефектов, которое задается как:

num_defects - num_fixes - num_blocks - num_ext_defects

Таким образом, для отчетности, num_defects теперь должно содержать: [28, 29, 17, 13, 12, 0, 2]

Я пытался:

num_defect.map { |i| i - num_fixes[i] - num_blocks[i] - num_ext_defects[i] }

, но это вызывает:

ноль не может быть принудительно введен в Fixnum

Любая помощь с благодарностью.

Ответы [ 5 ]

0 голосов
/ 04 декабря 2018

Использование Enumerator#each_with_object:

num_defect.each_with_index.with_object([]){ |(e, i), a| a << (e  - num_fixes[i] - num_blocks[i] - num_ext_defects[i]) }
#=> [28, 29, 17, 18, 13, 12, 0, 2]
0 голосов
/ 30 ноября 2018
[num_defect, num_fixes, num_blocks, num_ext_defects]
.transpose
.map{|first, *rest| first - rest.sum}
# => [28, 29, 17, 18, 13, 12, 0, 2]
0 голосов
/ 29 ноября 2018

Если я правильно вас понимаю, вы можете искать метод массива с именем each_index .

num_defect.each_index do |i|
   num_defect[i] -= num_fixes[i] + num_blocks[i] + num_ext_defects[i]
end
0 голосов
/ 29 ноября 2018
require 'matrix'

(Vector.elements(num_defect) - Vector.elements(num_fixes) -
 Vector.elements(num_blocks) - Vector.elements(num_ext_defects)).to_a
  #=> [28, 29, 17, 18, 13, 12, 0, 2]

При этом используются методы Vector :: elements и Vector # to_a .Можно написать Vector[*arr] вместо Vector.elements(arr), используя Vector :: [] .

Если num_defect должен быть мутирован, вы можете написать num_defect.replace(<above expression>).Если бы

arr = [num_defect, num_fixes, num_blocks, num_ext_defects]
  #=> [[30, 30, 20, 20, 18, 18, 5, 5],
  #    [ 1,  0,  3,  2,  1,  2, 2, 2],
  #    [ 0,  0,  0,  0,  2,  2, 1, 0],
  #    [ 1,  1,  0,  0,  2,  2, 2, 1]]

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

(Matrix.row_vector([1, *[-1]*(arr.size-1)]) * Matrix.rows(arr)).to_a.first
  #=> [28, 29, 17, 18, 13, 12, 0, 2]

, где

[1, *[-1]*(arr.size-1)]
  #=> [1, -1, -1, -1]

Это было бы удобно и относительно вычислительно эффективно, если бы arr имелбольшее количество элементов, чем в примере.

При этом используются методы Matrix Matrix :: row_vector , Matrix :: lines и Matrix # to_a .Можно написать Matrix[*arr] вместо Matrix.rows(arr), используя Matrix :: [] .Однако одно из преимуществ использования rows заключается в том, что можно добавить аргумент false (Matrix.rows(arr, false)), чтобы избежать копирования элементов arr при создании объекта Matrix.

0 голосов
/ 29 ноября 2018

С

num_defect.map { |i|

i - это элемент массива, а не его индекс.Если вы хотите, чтобы ваш map работал правильно, вам также понадобится индекс:

num_defect.map.with_index do |element, index|
  element - num_fixes[index] - num_blocks[index] - num_ext_defects[index]
end

Используйте map! вместо map, чтобы изменить num_defect.

Или, если вы хотите более приятную версию:

a = [30,30,20,20,18,18,5,5]
b = [ 1, 0, 3, 2, 1, 2,2,2]
c = [ 0, 0, 0, 0, 2, 2,1,0]
d = [ 1, 1, 0, 0, 2, 2,2,1]

a.zip(b,c,d).map { |arr| arr.inject(:-) }
#  => [28, 29, 17, 18, 13, 12, 0, 2]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...