class Array
def scanl(init, &f)
return [init] if empty?
reduce([init]){ |xs, x| xs << f.(xs.last, x) }
end
def scanl1(&f)
return if empty? # might consider returning []
x, *xs = self
xs.scanl(x, &f)
end
end
字符串 一般化为Enumerable,返回Enumerator s:
module Enumerable
def self._scanl(enum, a, &f)
Enumerator.new do |y|
y << a
loop { b = enum.next; y << (a = f.(a, b)) }
end
end
def scanl(a, &f)
enum = each_entry
Enumerable._scanl(enum, a, &f)
end
def scanl1(&f)
enum = each_entry
init = enum.next rescue return # might consider returning [].each_entry
Enumerable._scanl(enum, init, &f)
end
end
require 'spec_helper'
class Array
def scanl accumulator, &block
results = [accumulator] + self
results.each_with_index do |e, i|
results[i] = block.call(accumulator, e)
accumulator = results[i]
end
results
end
end
describe "#scanl" do
it 'is similar to foldl, but returns a list of successive reduced values from the left' do
# example from http://learnyouahaskell.com/higher-order-functions
expect([3, 5, 2, 1].scanl(0, &:+)).to eq([0,3,8,10,11])
end
end
4条答案
按热度按时间lc8prwob1#
你可以使用
reduce()
并自己实现它。字符串
或者,您可以使用
map()
并将初始元素放在数组前面。型
drnojrws2#
在Ruby 2.0中,
Enumerator
类存在,我们可以构建一个更好的实现,它可以在无限范围内正常工作:字符串
这样使用它:
型
8tntrjer3#
使用普通阵列操作:
字符串
一般化为
Enumerable
,返回Enumerator
s:型
示例如下:
型
wooyq4lh4#
也许可以写一个更好的版本,但这是我想到的:
字符串
我考虑过把
scanl
改成只取一个方法名,比如:+
,而不是像reduce
那样的块。