2008-08-06 23 views
18

Zastanawiam się, czy istnieje sposób, aby robić to, co mogę zrobić, poniżej Python, Ruby:wartości Mapowanie z dwóch tablicy w Ruby

sum = reduce(lambda x, y: x + y, map(lambda x, y: x * y, weights, data)) 

Mam dwie tablice równych rozmiarach z wagami i danych ale nie mogę znaleźć funkcji podobnej do mapy w Ruby, zmniejszam pracę.

Odpowiedz

13

@Michiel de Mare

Twój Ruby 1.9 Przykładem może być skrócony trochę dalej:

weights.zip(data).map(:*).reduce(:+) 

Należy również pamiętać, że w Ruby 1.8, jeśli wymagają ActiveSupport (od Rails) można użyć:

weights.zip(data).map(&:*).reduce(&:+) 
+0

To nie działa na mnie na Ruby 1.9.3 (ArgumentError). '[1,2,3] .zip ([4,5,6]) map (: *) ' –

+0

@Fe lixRabe: Wygląda na to, że rubin zmienił sposób, w jaki argumenty są przetwarzane w tego rodzaju proc. Naprawdę nie znam żadnych szczegółów, ponieważ nie tknąłem rubinu w ciągu kilku lat. –

1

Funkcja Array.zip wykonuje elementarną kombinację tablic. To nie jest całkiem czysty jak składni Pythona, ale tutaj jest jeden sposób można użyć:

weights = [1, 2, 3] 
data = [4, 5, 6] 
result = Array.new 
a.zip(b) { |x, y| result << x * y } # For just the one operation 

sum = 0 
a.zip(b) { |x, y| sum += x * y } # For both operations 
1

Ruby ma map metodę (a.k.a. metody collect), które mogą być stosowane do każdego Enumerable obiektu. Jeśli numbers jest tablica numerów dodaje linia Ruby

numbers.map{|x| x + 5} 

jest odpowiednikiem linii w poniższej Pythonie

map(lambda x: x + 5, numbers) 

Aby uzyskać więcej szczegółów, patrz here lub here.

5

W Ruby 1.9:

weights.zip(data).map{|a,b| a*b}.reduce(:+) 

W Ruby 1.8:

weights.zip(data).inject(0) {|sum,(w,d)| sum + w*d } 
0

Alternatywą dla mapy, która działa przez ponad 2 tablic, a także:

def dot(*arrays) 
    arrays.transpose.map {|vals| yield vals} 
end 

dot(weights,data) {|a,b| a*b} 

# OR, if you have a third array 

dot(weights,data,offsets) {|a,b,c| (a*b)+c} 

To może być również dodatkiem do tablica:

class Array 
    def dot 
    self.transpose.map{|vals| yield vals} 
    end 
end 

[weights,data].dot {|a,b| a*b} 

#OR 

[weights,data,offsets].dot {|a,b,c| (a*b)+c} 
0
weights = [1,2,3] 
data = [10,50,30] 

require 'matrix' 
Vector[*weights].inner_product Vector[*data] # => 200 
Powiązane problemy