Mappage des valeurs de deux tableaux dans Ruby
Question
Je me demande s'il existe un moyen de faire ce que je peux faire ci-dessous avec Python, en Ruby :
sum = reduce(lambda x, y: x + y, map(lambda x, y: x * y, weights, data))
J'ai deux tableaux de tailles égales avec les poids et les données mais je n'arrive pas à trouver une fonction similaire à map dans Ruby, réduisez mon travail.
La solution
@Michiel de Mare
Votre exemple Ruby 1.9 peut être un peu plus raccourci :
weights.zip(data).map(:*).reduce(:+)
Notez également que dans Ruby 1.8, si vous avez besoin d'ActiveSupport (depuis Rails), vous pouvez utiliser :
weights.zip(data).map(&:*).reduce(&:+)
Autres conseils
Dans Ruby 1.9 :
weights.zip(data).map{|a,b| a*b}.reduce(:+)
Dans Ruby 1.8 :
weights.zip(data).inject(0) {|sum,(w,d)| sum + w*d }
La fonction Array.zip effectue une combinaison de tableaux par éléments.Ce n'est pas aussi clair que la syntaxe Python, mais voici une approche que vous pouvez utiliser :
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 a un map
méthode (c.-à-d.le collect
méthode), qui peut être appliquée à n’importe quel Enumerable
objet.Si numbers
est un tableau de nombres, la ligne suivante en Ruby :
numbers.map{|x| x + 5}
est l'équivalent de la ligne suivante en Python :
map(lambda x: x + 5, numbers)
Une alternative à la map qui fonctionne également pour plus de 2 tableaux :
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}
Cela pourrait également être ajouté à Array :
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