在Ruby中映射两个数组的值

我想知道是否有办法在Ruby中用Python来做我能做的事情:

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

我有两个与权重和数据大小相同的数组,但是我似乎无法在Ruby中找到类似于map的函数,请减少我的工作量。

0
额外 编辑
意见: 2

6 答案

在Ruby 1.9中:

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

在Ruby 1.8中:

weights.zip(data).inject(0) {|sum,(w,d)| sum + w*d }
0
额外
weights = [1,2,3]
data    = [10,50,30]

require 'matrix'
Vector[*weights].inner_product Vector[*data] # => 200 
0
额外

@Michiel de Mare

您的Ruby 1.9示例可以进一步缩短:

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

另请注意,在Ruby 1.8中,如果您需要ActiveSupport(来自Rails),您可以使用:

weights.zip(data).map(&:*).reduce(&:+)
0
额外
@FelixRabe:看起来ruby已经改变了在这类过程中如何处理参数。我真的不知道任何细节,因为几年后我没有碰过红宝石。
额外 作者 Kevin Ballard,
这对Ruby 1.9.3(ArgumentError)无效: [1,2,3] .zip([4,5,6])。map(:*)
额外 作者 Felix Rabe,

Ruby有一个 map 方法(a.k.a. collect 方法),它可以应用于任何 Enumerable 对象。如果 numbers 是一个数字数组,Ruby中的以下行:

numbers.map{|x| x + 5}

相当于Python中的以下行:

map(lambda x: x + 5, numbers)

有关更多详细信息,请参见此处此处

0
额外

Array.zip函数执行数组的元素组合。它不像Python语法那么干净,但是可以使用以下一种方法:

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
0
额外

另一种适用于2个以上阵列的地图:

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}

这也可以添加到数组中:

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
额外