ruby 在多个数组上映射一个函数
Posted
技术标签:
【中文标题】ruby 在多个数组上映射一个函数【英文标题】:ruby map a function over multiple arrays 【发布时间】:2021-03-03 09:50:32 【问题描述】:我有 2 个数组
asc = [0, 1, 2, 3, 4, 5]
dsc = [5, 4, 3, 2, 1, 0]
我想要一个新数组,它是 asc 和 dsc 中每个对应项相乘的结果
我已经习惯了 Clojure,我只会 map
(map #(* %1 %2) asc dsc) ;=> (0 4 6 6 4 0)
它们在 Ruby 中是等价的吗?在 Ruby 中执行此操作的惯用方式是什么?
我是 Ruby 新手,但它似乎有非常简洁的解决方案,所以我认为我遗漏了一些东西。
我只是写吗:
i = 0
res = []
while i < asc.length() do
res.append(asc[i] * dsc[i])
end
【问题讨论】:
您忘记了asc
和dsc
中的逗号。
【参考方案1】:
使用zip 将每个元素与其对应的两个元素数组中的元素组合起来,而不是映射
asc.zip(dsc).map |a, b| a * b
=> [0, 4, 6, 6, 4, 0]
【讨论】:
【参考方案2】:看来dsc
("descending") 派生自asc
("ascending"),在这种情况下你可以这样写:
asc.each_index.map |i| asc[i] * asc[-i-1]
#=> [0, 4, 6, 6, 4, 0]
你也可以写:
[asc, dsc].transpose.map |a,d| a*d
#=> [0, 4, 6, 6, 4, 0]
或:
require 'matrix'
Matrix[asc].hadamard_product(Matrix[dsc]).to_a.first
#=> [0, 4, 6, 6, 4, 0]
见Matrix#hadamard_product。
【讨论】:
【参考方案3】:使用map
和with_index
:
asc = [0, 1, 2, 3, 4, 5]
dsc = [5, 4, 3, 2, 1, 0]
res = asc.map.with_index |el, i| el * dsc[i]
puts res.inspect
# [0, 4, 6, 6, 4, 0]
或者,使用each_index
和map
:
res = asc.each_index.map |i| asc[i] * dsc[i]
【讨论】:
我认为zip
会更常用,但与您的答案相比,它具有创建临时数组(asc.zip(dsc)
)的缺点。你可以改为写这个asc.each_index.map |i| asc[i] * dsc[i]
(虽然我不认为两者都是首选)。
@CarySwoveland 感谢您提出另一种解决方案!我将其添加到我的答案中。
@CarySwoveland 另一种避免临时数组的方法是asc.enum_for(:zip, dsc)
【参考方案4】:
你也可以这样写:
asc = [0, 1, 2, 3, 4, 5]
dsc = [5, 4, 3, 2, 1, 0]
p asc.zip(dsc).collect|z| z.inject(:*)
[0, 4, 6, 6, 4, 0]
【讨论】:
以上是关于ruby 在多个数组上映射一个函数的主要内容,如果未能解决你的问题,请参考以下文章