【发布时间】:2011-12-22 15:41:56
【问题描述】:
我想用Array 做类似join 的事情,但我不想得到String 的结果,我想得到Array。我会称之为interpolate。例如,给定:
a = [1, 2, 3, 4, 5]
我希望:
a.interpolate(0) # => [1, 0, 2, 0, 3, 0, 4, 0, 5]
a.interpolate{Array.new} # => [1, [], 2, [], 3, [], 4, [], 5]
获得这个的最佳方法是什么?我需要它来获取块的原因是因为当我将它与块一起使用时,我希望每个插值器都有不同的实例。
在得到很多人的好答案后,我想出了一些修改过的答案。
这是对 tokland 答案的修改。我让它接受nil 为conj1。并且还将if conj2 条件移到flat_map 循环之外以使其更快。
class Array
def interpolate conj1 = nil, &conj2
return [] if empty?
if conj2 then first(length - 1).flat_map{|e| [e, conj2.call]}
else first(length - 1).flat_map{|e| [e, conj1]}
end << last
end
end
这是对 Victor Moroz 答案的修改。我添加了接受块的功能。
class Array
def interpolate conj1 = nil, &conj2
return [] if empty?
first, *rest = self
if conj2 then rest.inject([first]) {|a, e| a.push(conj2.call, e)}
else rest.inject([first]) {|a, e| a.push(conj1, e)}
end
end
end
基准测试后,第二个看起来更快。看来flat_map虽然看起来很漂亮,但速度很慢。
【问题讨论】:
-
为什么用
Array.new屏蔽?你不能把它作为参数传递吗? -
@Linux_iOS.rb.cpp.c.lisp.m.sh 也许我的例子不好,但有时,我需要为每个插值器使用不同的实例。
-
这是有道理的。这意味着我的回答一文不值。对不起。