Zuordnen von Werten aus zwei Arrays in Ruby
Frage
Ich frage mich, ob es eine Möglichkeit gibt, das, was ich unten tun kann, mit Python in Ruby zu tun:
sum = reduce(lambda x, y: x + y, map(lambda x, y: x * y, weights, data))
Ich habe zwei Arrays gleicher Größe mit den Gewichten und Daten, kann aber anscheinend keine ähnliche Funktion wie „map“ in Ruby finden.
Lösung
@Michiel de Mare
Ihr Ruby 1.9-Beispiel kann etwas weiter gekürzt werden:
weights.zip(data).map(:*).reduce(:+)
Beachten Sie außerdem, dass Sie in Ruby 1.8 Folgendes verwenden können, wenn Sie ActiveSupport (von Rails) benötigen:
weights.zip(data).map(&:*).reduce(&:+)
Andere Tipps
In Ruby 1.9:
weights.zip(data).map{|a,b| a*b}.reduce(:+)
In Ruby 1.8:
weights.zip(data).inject(0) {|sum,(w,d)| sum + w*d }
Die Funktion Array.zip führt eine elementweise Kombination von Arrays durch.Sie ist nicht ganz so sauber wie die Python-Syntax, aber hier ist ein Ansatz, den Sie verwenden könnten:
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
Ruby hat eine map
Methode (auch bekannt alsDie collect
Methode), die auf jedes angewendet werden kann Enumerable
Objekt.Wenn numbers
ist ein Array von Zahlen, die folgende Zeile in Ruby:
numbers.map{|x| x + 5}
ist das Äquivalent der folgenden Zeile in Python:
map(lambda x: x + 5, numbers)
Eine Alternative für die Karte, die auch für mehr als 2 Arrays funktioniert:
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}
Dies könnte auch zu Array hinzugefügt werden:
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}
weights = [1,2,3]
data = [10,50,30]
require 'matrix'
Vector[*weights].inner_product Vector[*data] # => 200