【发布时间】:2010-12-22 10:12:42
【问题描述】:
比如“stack”这个词,我想得到一个数组,比如:
['s', 'st', 'sta', ... 'stack', 't', 'ta', ... , 'c', 'ck', 'k']
我是通过这样的代码做到的:
def split_word(str)
result = []
chas = str.split("")
len = chas.size
(0..len-1).each do |i|
(i..len-1).each do |j|
result.push(chas[i..j].join)
end
end
result.uniq
end
有没有更好更干净的方法来做到这一点?谢谢。
【问题讨论】:
-
一般建议:最好使用 map(函数式)而不是遵循“init empty + iterate + push + return”(命令式)模式
-
@tokland:您所描述的不是 map(Ruby 中的
collect),而是 fold 或更一般的 catamorphism(Ruby 中的inject或reduce)。 -
@Jörg,我所说的模式不是折叠:“a = []; [1,2,3].each { |x| a
-
好吧,地图总是可以写成折叠的......无论如何,把术语放在一边我希望前面评论中的例子能说明我的意图。问题是类型,用 Haskell 术语来说,“a -> [a]”,所以对我来说,地图似乎是最自然的解决方案。
-
@tokland:嗯,
map只是fold的一个特例:-) 基本上,map f = foldr (λx y → f x : y) []。您在评论中给出的一般描述描述了fold的一般情况,但对于您正确的具体示例,这当然是map。特别是当init empty是一个与原始集合相同类型的集合,而iterate只是应用了一个转换函数,而push包含所有元素,那么它就是一个@987654334 @。实际上,fold是通用的:any 迭代(map、select、count等,甚至是each)都可以表示为fold。