面向对象Ruby中的向量加法

时间:2016-05-29 15:45:53

标签: ruby vector

我必须在Ruby中使用构造函数创建类,该构造函数初始化二维向量。 X和Y是矢量的长度。在这个类中,我必须创建一个方法,它将添加两个向量,这些向量是Vector2D类的对象。

class Vector2D
    def initialize(x, y)
        @x = x
        @y = y
    end
    def add 
        return "Vector addition"
    end
end

vector1 = Vector2D.new(3,4)
vector2 = Vector2D.new(1,2)

puts vector1.add

我不知道如何实现“添加”方法。我不知道如何将这两个向量作为参数发送,我不知道我必须在哪个对象上调用此方法。

2 个答案:

答案 0 :(得分:3)

我相信这可能就是你想要的。

<强>代码

class Vector2D
  attr_reader :x

  def initialize(*x)
    @x = x
  end

  def add(other)
    x.zip(other.x).map { |x,y| x+y }
  end
end

示例

vector1 = Vector2D.new(3,4)
vector2 = Vector2D.new(1,2)

vector1.add(vector2)
  #=> [4, 6] 

该方法适用于任何大小的矢量,但是要相互添加它们当然必须具有相同的大小。

Vector2D.new(1,2,3,4).add Vector2D.new(5,6,7,8)
  #=> [6, 8, 10, 12] 
Vector2D.new(1).add Vector2D.new(2)
  #=> [3] 
Vector2D.new().add Vector2D.new()
  #=> [] 

<强>解释

使用参数initialize调用

*x*被称为&#34; splat&#34;运营商。 This link对如何使用它给出了很好的解释。如果您将数组传递给Class::newVector2D.new([3,4])),那么您将不需要splat运算符。 (更多内容见下文。)

add我们计算

a = vector1.x.zip(vector2.x)
  #=> [[3, 1], [4, 2]] 

然后

a.map { |x,y| x+y }
  #=> [4, 6]

请注意

x.zip(other.x).map { |x,y| x+y }

相同
self.x.zip(other.x).map { |x,y| x+y }

那是因为当一个方法(这里是getter x)没有明确的接收者时(就像我们写self.x那样,self是接收者) ,Ruby假设接收者是self。当self.my_method安全时,您会经常看到my_method。一些Rubiests选择前者因为他们认为它更清楚(即使他们知道它是不必要的)。我不碰巧在那个营地。

我们可以写

@x.zip(other.x).map { |x,y| x+y }

直接引用实例变量@x,而不是通过其getter。两种方式都很好。

<强>观察

最好写一下:

  def initialize(x)
    @x = x
  end

vector1 = Vector2D.new([3,4])

强调你传递数组。

当两个数组长度相同时,您可以互换使用Enumerable#zipArray#transpose

def add(other)
  [x, other.x].transpose.map { |y,z| y+z }
end

那是因为

[3,4].zip([1,2])
  #=> [[3, 1], [4, 2]] 
[[3,4], [1,2]].transpose
  #=> [[3, 1], [4, 2]] 

答案 1 :(得分:1)

如果要以OO方式添加两个向量,则在发送add消息并返回结果(可以为nil)时,将一个向量作为参数传递给另一个向量。

通常情况如下:

result = receiver.message(argument)

所以你的向量应该有一个add方法,它将另一个向量作为参数。我会返回一个新的向量作为结果(但你也可以返回一个带x / y的数组),这样你就可以继续计算了。

class Vector2D
  attr_reader :x, :y

  def initialize(x, y)
    @x = x
    @y = y
  end

  def add(other)
    Vector2D.new(x + other.x, y + other.y)
  end

  def inspect
    "(#{x},#{y})"
  end
end


vector1 = Vector2D.new(3,4)
vector2 = Vector2D.new(1,2)

vector3 = vector1.add(vector2)

p vector1 # => (3,4)
p vector2 # => (1,2)
p vector3 # => (4,6)
p vector3.add(vector3) # )> (8,12)

以类似的方式,您可以添加对矢量计算有用的其他操作。可能是lengthsubtract等等。

如果你想添加一些语法糖,你可以将方法add别名为+。在 add

的定义之后添加以下行
alias_method :+, :add

这将使您能够写

vector3 = vector1 + vector2