
Submitted by neoneye (Sun Feb 20 08:02:48 UTC 2005)
[1, 2, 3].inject(nil){|a,b| a ? (a+[0, b]) : [b]} #=> [1, 0, 2, 0, 3]
[1,2,3].map{|x|[x,0]}.flatten[0..-2] #=> [1, 0, 2, 0, 3]
However I like the following because of its readability.
res = [] [1, 2, 3].each_with_index do |a,i|
res << 0 if i!=0 res << a
end res #=> [1, 0, 2, 0, 3]
None of these are really nice solutions.
1 argument, without block:
[1, 2, 3, 4].interpolate("a") #=> [1, "a", 2, "a", 3, "a", 4]
no arguments, with a block:
[8,6,4,2,0].interpolate{|a,b|(a+b)/2} #-> [8,7,6,5,4,3,2,1,0]
no arguments, with block:
[0, 10, 100, 1000].interpolate{|a,b,index|"#{(a+b)/2} #{index}"}
#=> [0, "5 0", 10, "55 1", 100, "550 2", 1000]
with arguments and block:
[0, 10, 100, 1000,
10000].interpolate(+1,-1){|a,b,index,sign|"#{(a+b)/2*sign} #{index}"}
#=> [0, "5 0", 10, "-55 1", 100, "550 2", 1000, "-5500 3", 10000]
2+ arguments, without block:
[1, 2, 3, 4, 5].interpolate("a","b","c")
#=> [1, "a", 2, "b", 3, "c", 4,
"a", 5]
class Array
def interpolate(*args,&block)
out = Array.new
first = true
last = nil
if not block and args.empty?
raise ArgumentError,"wrong number of arguments (0 for 1)"
elsif not args.empty? and block
apos = 0
self.each_index do |i|
if not first
out << block.call(last,self[i],i-1,args[apos])
apos+=1
apos%=args.size
end
out << self[i]
last = self[i]
first=false
end
out
elsif not args.empty?
apos = 0
self.each do |i|
if not first
out << args[apos]
apos+=1
apos%=args.size
end
out << i
last = i
first=false
end
out
else
self.each_index do |i|
if not first
out << block.call(last,self[i],i-1)
end
out << self[i]
last = self[i]
first=false
end
out
end
end
def interpolate!(*args,&block)
self.replace(self.interpolate(*args,&block))
end
end

| Comments | Current voting | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|


RCRchive copyright © David Alan Black, 2003-2005.
Powered by .
[1,2,3].zip(0) # => [1,0,2,0,3]
I like the idea, but I have a couple issues with the implementation:
A slightly simpler and more specific implementation:
[1,10,100,1000].intersperse{|pre, post| "#{pre}:#{post}" }[1,10,100,1000].intersperse(:a,:b){|pre, val, post| "#{pre}:#{val}:#{post}" }Also, I think it should be an Enumerable method rather than just Array.
I am voting in favor of this, on the condition that the above name ("intersperse") is used instead of "interpolate".
I would also support the name "sprinkle" :) - GavinKistner
English is not my native language. "Intersperse" sounds good to me :-)
-- Simon Strandgaard