私はこれがあなたが望むかもしれないと信じています。彼らはもちろん、同じサイズでなければなりませんしなければならない別のものを追加するのに
コード
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
と呼ばれています。 *
は「スプラット」演算子と呼ばれます。 This linkは、どのように使用されているかをよく説明しています。 Class::new(Vector2D.new([3,4])
)に配列を渡した場合、splat演算子は必要ありません。 (以下、その上より。)我々は
a = vector1.x.zip(vector2.x)
#=> [[3, 1], [4, 2]]
を計算add
で
は次に
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
と書いた場合のように)、受信者はself
とみなされます。 my_method
が安全になった場合は、多くの場合、self.my_method
が表示されます。 Rubiestsの中には、たとえそれが不必要であることが分かっていても、もっと明確に思えるので、Rubiestsの前者を選ぶ人もいます。私はそのキャンプにいることはありません。
我々は代わりに直接ではなく、そのゲッターを通じて@x
変数のインスタンスを参照する
@x.zip(other.x).map { |x,y| x+y }
を書くことができます。どちらの方法も問題ありません。
def initialize(x)
@x = x
end
と
vector1 = Vector2D.new([3,4])
をあなたは、配列を渡している強調すること:書くことが好ましいかもしれない
観察
。二つの配列が同じ長さである場合には
あなたは、交換可能にEnumerable#zipとArray#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]]
を書くこと後ができます
add
の定義を次の行を追加します –
あなたは '+'を使って 'vector1のようなコードを使って2つのベクトルを追加する方法を実装するには、この答えを見てみるといいかもしれません(http://stackoverflow.com/questions/5556124/ruby-defining-operator-procedure)。 + vector2' –