JavaScript `减少` 到 Ruby `减少`
JavaScript `reduce` to Ruby `reduce`
在 JavaScript 中,一个 reduce
函数可能如下所示:
array.reduce((acc, cur, idx, arr) => {
// body
}, starting_value);
我正在尝试以某种方式获得 arr
参数,它是原始数组的副本,我已经多次看到它很有用。这是我所能接受的:
array.each_with_index.reduce (starting_value) do |acc (cur, idx)|
# body
end
我浏览 Ruby 文档已经有一段时间了(我实际上复制了 .each_with_index
,因为我在某个地方找到了它),正在寻找任何像我一直在寻找的东西寻找。
老实说,从功能上讲,我可以将它分成多行并将某些内容存储在一个变量中,但是如果我可以将我的功能方法保留在 JavaScript 和 Ruby 中,我会非常高兴.
本质上:有什么方法可以在正文中获取arr
参数吗?
reduce
– 作为一个 Enumerable
方法 – 不知道它正在枚举的集合。
您必须自己合并数组,例如通过 then
/ yield_self
:
[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
或链中某处:
[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
可以创建自定义 reduce
方法:
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
块的第三个参数将是对集合的引用:
> [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
当然,这个实现会比原来的慢:
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)
在 JavaScript 中,一个 reduce
函数可能如下所示:
array.reduce((acc, cur, idx, arr) => {
// body
}, starting_value);
我正在尝试以某种方式获得 arr
参数,它是原始数组的副本,我已经多次看到它很有用。这是我所能接受的:
array.each_with_index.reduce (starting_value) do |acc (cur, idx)|
# body
end
我浏览 Ruby 文档已经有一段时间了(我实际上复制了 .each_with_index
,因为我在某个地方找到了它),正在寻找任何像我一直在寻找的东西寻找。
老实说,从功能上讲,我可以将它分成多行并将某些内容存储在一个变量中,但是如果我可以将我的功能方法保留在 JavaScript 和 Ruby 中,我会非常高兴.
本质上:有什么方法可以在正文中获取arr
参数吗?
reduce
– 作为一个 Enumerable
方法 – 不知道它正在枚举的集合。
您必须自己合并数组,例如通过 then
/ yield_self
:
[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
或链中某处:
[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
可以创建自定义 reduce
方法:
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
块的第三个参数将是对集合的引用:
> [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
当然,这个实现会比原来的慢:
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)