首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript `reduce`转换为Ruby `reduce`

JavaScript `reduce`转换为Ruby `reduce`
EN

Stack Overflow用户
提问于 2020-05-20 17:16:05
回答 2查看 304关注 0票数 1

在JavaScript中,reduce函数可能如下所示:

代码语言:javascript
复制
array.reduce((acc, cur, idx, arr) => {
    // body
}, starting_value);

我试图以某种方式拥有arr参数,它是原始数组的副本,我已经多次看到它是有用的。这就是我所能做到的:

代码语言:javascript
复制
array.each_with_index.reduce (starting_value) do |acc (cur, idx)|
    # body
end

我浏览Ruby文档已经有相当长的一段时间了(实际上我复制了.each_with_index,因为我在某个地方找到了它),寻找任何与我一直在寻找的东西相去甚远的东西。

老实说,从函数上讲,我可以把它分成多行并存储在一个变量中,但如果我能在JavaScript中使用Ruby保持我的函数式方法,我会非常高兴。

本质上:有没有办法在正文中获取arr参数?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-20 18:30:37

作为一个Enumerable方法,reduce并不知道它所枚举的集合。

您必须自己整合阵列,例如通过then / yield_self

代码语言:javascript
复制
[1, 2, 3].then do |arr|
  arr.each_with_index.reduce(4) do |acc, (cur, idx)|
    p acc: acc, cur: cur, idx: idx, arr: arr
    acc + cur
  end
end
# {:acc=>4, :cur=>1, :idx=>0, :arr=>[1, 2, 3]}
# {:acc=>5, :cur=>2, :idx=>1, :arr=>[1, 2, 3]}
# {:acc=>7, :cur=>3, :idx=>2, :arr=>[1, 2, 3]}
#=> 10

或链条中的某个位置:

代码语言:javascript
复制
[1, 2, 3].then do |arr|
  arr.map { |x| x * 2 }.then do |arr_2|
    arr_2.each_with_index.reduce(4) do |acc, (cur, idx)|
      p acc: acc, cur: cur, idx: idx, arr: arr, arr_2: arr_2
      acc + cur
    end
  end
end
# {:acc=>4, :cur=>2, :idx=>0, :arr=>[1, 2, 3], :arr_2=>[2, 4, 6]}
# {:acc=>6, :cur=>4, :idx=>1, :arr=>[1, 2, 3], :arr_2=>[2, 4, 6]}
# {:acc=>10, :cur=>6, :idx=>2, :arr=>[1, 2, 3], :arr_2=>[2, 4, 6]}
#=> 16
票数 1
EN

Stack Overflow用户

发布于 2020-05-20 19:37:47

可以创建自定义reduce方法:

代码语言:javascript
复制
module Enumerable
  def reduce_with_self(initial_or_sym, sym = nil)
    if initial_or_sym.is_a?(Symbol)
      operator = initial_or_sym
      initial = nil
    else
      initial = initial_or_sym
      operator = sym
    end
    accumulator = initial
    each_with_index do |item, index|
      if index.zero? && initial.nil?
        accumulator = item
        next
      end
      accumulator = operator.nil? ? yield(accumulator, item, self) : accumulator.send(operator, item)
    end
    accumulator
  end
end

块的第三个参数将是对集合的引用:

代码语言:javascript
复制
> [1,2,3,4].reduce_with_self(0) do |acc, item, array|
>   p array
>   acc += item
> end
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
 => 10

> [1,2,3,4].reduce_with_self(2,:+)
 => 12 

> [1,2,3,4].reduce_with_self(:+)
 => 10 

当然,这个实现会比原来的慢:

代码语言:javascript
复制
require 'benchmark'

Benchmark.bm do |x|
  x.report('reduce') { 1000.times { (0..10000).reduce(0) { |acc, item| acc += item } } }
  x.report('reduce_with_self') { 1000.times { (0..10000).reduce_with_self(0) { |acc, item, array| acc += item } } }
end

       user     system      total        real
reduce  0.501833   0.000000   0.501833 (  0.502698)
reduce_with_self  0.955978   0.000000   0.955978 (  0.956809)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61909374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档