2009-06-17 39 views
11

Làm thế nào để thực hiện Ngoài ra vector trong Ruby đểLàm cách nào để thực hiện thêm vectơ trong Ruby?

[100, 100] + [2, 3] 

mang

[102, 103] 

(thay vì tham gia hai mảng)?

Hoặc nó có thể được điều hành khác quá, chẳng hạn như

[100, 100] @ [2, 3] 

hoặc

[100, 100] & [2, 3] 
+0

Nếu điều này là lisp, giải pháp sẽ là sử dụng bản đồ: (bản đồ + '(100 100)' (2 3)) => (102 103). Có lẽ Ruby có một chức năng tương tự? –

Trả lời

32

Xem lớp Vector:

require "matrix" 

x = Vector[100, 100] 
y = Vector[2, 3] 
print x + y 

E:\Home> ruby t.rb 
Vector[102, 103] 

Xem vectorops cho các hoạt động bổ sung về vectơ:

& hellip; các hoạt động sau đây làm việc như mong đợi

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] 

Xem thêm vectorops.

3

Hoặc nếu bạn muốn tùy ý hành vi kích thước đa dạng đó (như bổ sung vector toán học)

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] 

Việc thiếu bản đồ kiểu lisp là khá đáng ghét.

18

Mảng # zip:

$ irb 
irb(main):001:0> [100,100].zip([2,3]).map { |e| e.first + e.last } 
=> [102, 103] 

ngắn:

irb(main):002:0> [100,100].zip([2,3]).map { |x,y| x + y } 
=> [102, 103] 

tổng quát đến> 2 chiều với #inject:

irb(main):003:0> [100,100,100].zip([2,3,4]).map { |z| z.inject(&:+) } 
=> [102, 103, 104] 
0
module PixelAddition 
    def +(other) 
    zip(other).map {|num| num[0]+num[1]} 
    end 
end 

Sau đó, bạn có thể tạo ra một mảng lớp con kết hợp trong mô-đun hoặc thêm hành vi để mảng cụ thể như:

class <<an_array 
    include PixelAddition 
end 
+1

Sử dụng tuyệt vời các mô-đun, nhưng có một số trường hợp của Mảng giải thích toán tử + theo cách khác với các trường hợp khác thực sự làm tôi sợ. Bạn thậm chí có thể nhận được các tình huống trong đó (a + b)! = (B + a). – molf

3

Khi ở Rome..monkeypatch.

module Enumerable 
    def sum 
    inject &:+ 
    end 

    def vector_add(*others) 
    zip(*others).collect &:sum 
    end 
end 

Sau đó, bạn có thể thực hiện a.vector_add (b) và hoạt động. Tôi tin rằng điều này đòi hỏi Ruby 1.8.7, hoặc một phần mở rộng thêm Symbol.to_proc. Bạn cũng có thể thêm số lượng vectơ tùy ý theo cách này.

2

Cũng giống như bên lề, nếu bạn (như tôi) cảm thấy không hài lòng với các hoạt động được lớp Vector mặc định từ ruby ​​cung cấp, hãy xem xét cho hình dạng của tôi, thêm một số chức năng mà tôi mong đợi từ một Vector phù hợp thực hiện.

Các vấn đề liên quan