如何在Ruby中执行向量添加以便
[100, 100] + [2, 3]
产量
[102, 103]
(而不是连接两个数组)?
或者它也可以是其他运营商,例如
[100, 100] @ [2, 3]
或
[100, 100] & [2, 3]
答案 0 :(得分:33)
请参阅Vector课程:
require "matrix"
x = Vector[100, 100]
y = Vector[2, 3]
print x + y
E:\Home> ruby t.rb
Vector[102, 103]
有关向量的其他操作,请参阅vectorops:
......以下操作的工作方式与预期相同
v1 = Vector[1,1,1,0,0,0]
v2 = Vector[1,1,1,1,1,1]
v1[0..3]
# -> Vector[1,1,1]
v1 += v2
# -> v1 == Vector[2,2,2,1,1,1]
v1[0..3] += v2[0..3]
# -> v1 == Vector[2,2,2,0,0,0]
v1 + 2
# -> Vector[3,3,3,1,1,1]
另见vectorops。
答案 1 :(得分:18)
阵列#ZIP:
$ irb
irb(main):001:0> [100,100].zip([2,3]).map { |e| e.first + e.last }
=> [102, 103]
更短的:
irb(main):002:0> [100,100].zip([2,3]).map { |x,y| x + y }
=> [102, 103]
使用#inject:
推广到> 2维irb(main):003:0> [100,100,100].zip([2,3,4]).map { |z| z.inject(&:+) }
=> [102, 103, 104]
答案 2 :(得分:3)
或者,如果您想要该种类的任意维度行为(如数学向量添加)
class Vector < Array
def +(other)
case other
when Array
raise "Incorrect Dimensions" unless self.size == other.size
other = other.dup
self.class.new(map{|i| i + other.shift})
else
super
end
end
end
class Array
def to_vector
Vector.new(self)
end
end
[100,100].to_vector + [2,3] #=> [102,103]
缺乏lisp风格的地图是非常令人讨厌的。
答案 3 :(得分:3)
在罗马...... monkeypatch。
module Enumerable
def sum
inject &:+
end
def vector_add(*others)
zip(*others).collect &:sum
end
end
然后你可以做a.vector_add(b)并且它可以工作。我相信这需要Ruby 1.8.7,或者添加Symbol.to_proc的扩展。您也可以通过这种方式添加任意数量的矢量。
答案 4 :(得分:2)
正如旁注,如果你(像我一样)对ruby中默认Vector类提供的操作感到不满意,可以考虑给我的gem https://github.com/psorowka/vectorops一个看,这增加了我期望的一些功能。一个合适的Vector实现。
答案 5 :(得分:0)
module PixelAddition
def +(other)
zip(other).map {|num| num[0]+num[1]}
end
end
然后,您可以创建一个混合在模块中的Array子类,或者将行为添加到特定的数组中,如:
class <<an_array
include PixelAddition
end