From: Robert Klemme Date: 2003-07-22T14:08:36+09:00 Subject: A new Version of Enumerable#inject (was Re: chaining comparisons) "Robert Klemme" schrieb im Newsbeitrag news:bfgvjq$e7itp$1@ID-52924.news.uni-berlin.de... (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 true irb(main):389:0> b.inject(true) {|cond, x, y| cond && x 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