如何减去整数数组

时间:2018-11-29 09:24:26

标签: arrays ruby

我有四个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 :(得分:4)

使用

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]

答案 1 :(得分:2)

如果我对您的理解正确,那么您可能正在寻找一种名为 each_index 的数组方法。

num_defect.each_index do |i|
   num_defect[i] -= num_fixes[i] + num_blocks[i] + num_ext_defects[i]
end

答案 2 :(得分:2)

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::elementsVector#to_a。可以使用Vector::[]来代替Vector[*arr]来写Vector.elements(arr)

如果要对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_vectorMatrix::rowsMatrix#to_a。可以使用Matrix::[]来代替Matrix[*arr]来写Matrix.rows(arr)。但是,使用rows的一个好处是,可以添加参数falseMatrix.rows(arr, false))以避免在创建{{1时复制arr的元素}}对象。

答案 3 :(得分:0)

[num_defect, num_fixes, num_blocks, num_ext_defects]
.transpose
.map{|first, *rest| first - rest.sum}
# => [28, 29, 17, 18, 13, 12, 0, 2]

答案 4 :(得分:0)

使用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]