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

【问题讨论】:

您忘记了ascdsc 中的逗号。 【参考方案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】:

使用mapwith_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_indexmap

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 在多个数组上映射一个函数的主要内容,如果未能解决你的问题,请参考以下文章

Pandas DataFrame 函数应用和映射

如何使函数在映射数组中的单个项目而不是数组中的每个项目上执行?

如何存储多个数据类型的数组

在 Rails 上使用唯一 id ruby​​ 映射日期

映射一个数组,只修改匹配某个条件的元素

IIS7 上配置运行 Ruby CGI环境