(Now I start already at 36 talking to myself...)
Method Enumerable#connect might even be considert a library addenum, IMHO.
Maybe inject might be changed to yield one more parameter the way it is
shown here. What does Matz think? What do others think?
I'd like to propose a slightly different version of Enumerable#inject which
uses a sliding window on the enum and is compatible with the 1.8 version:
module Enumerable
def inject(val=nil, &bl)
raise "Block missing" unless bl
size = bl.arity
raise "Need block with at least 1 argument" if size == 0
size = size < 0 ? 1+size : size-1
args=[]
each do |e|
args.push e
if args.length == size
val = yield val, *args
args.shift
end
end
val
end
end
Now, apart from the usual inject things like sum, product and max
calculations you can do a lot of nice things like
irb(main):374:0* a=[1, 20, 30, 40, 41, 42, 88, 123]
=> [1, 20, 30, 40, 41, 42, 88, 123]
irb(main):375:0> b=[]
=> []
irb(main):376:0> # SMOOTH
irb(main):377:0* sm=[]
=> []
irb(main):378:0> a.inject(0){|idx, x, y| sm[idx] = (x+y).to_f / 2; idx+1}
=> 7
irb(main):379:0> sm
=> [10.5, 25.0, 35.0, 40.5, 41.5, 65.0, 105.5]
irb(main):380:0> sm=[]
=> []
irb(main):381:0> a.inject(0){|idx, x, y, z| sm[idx] = (x+y+z).to_f / 3;
idx+1}
=> 6
irb(main):382:0> sm
=> [17.0, 30.0, 37.0, 41.0, 57.0, 84.33333333]
irb(main):383:0> # WEIGHTED SMOOTHING
irb(main):384:0* sm=[]
=> []
irb(main):385:0> a.inject(0){|idx, x, y, z| sm[idx] = (x+y+y+z).to_f / 4;
idx+1}
=> 6
irb(main):386:0> sm
=> [17.75, 30.0, 37.75, 41.0, 53.25, 85.25]
irb(main):387:0> # TEST SORTED
irb(main):388:0* a.inject(true) {|cond, x, y| cond && x<y}
=> true
irb(main):389:0> b.inject(true) {|cond, x, y| cond && x<y}
=> true
irb(main):390:0> def ordered?(*args); args.inject(true) {|cond, x, y| cond
&& x<
y}; end
=> nil
irb(main):391:0> ordered? *a
=> true
irb(main):392:0> ordered? 1,2,4
=> true
irb(main):393:0>
What do you think?
robert