From: David Alan Black Date: 2002-03-31T11:20:45+09:00 Subject: Re: Array#join accept a codeblock? Hello -- On Fri, 29 Mar 2002, Tom Robinson wrote: > Is there some way to do something like Array#join that takes a > codeblock to tell it what to join up the array with? Something > like... > > ary = [1,2,3,4,5] > str = ary.myjoin { |idx| > if idx == 1 > ' ** ' > else > ' -- ' > end > } > > gives str as "1 -- 2 ** 3 -- 4 -- 5" > > I have written something like this below, but I was wondering if > there's anything like this in ruby, or if not maybe it could be added > to the next version. :) > > class Array > def myjoin > outstr = "" > self.each_index { |idx| > if idx == self.length - 1 > outstr += self[idx].to_s > else > outstr += self[idx].to_s + yield(idx).to_s > end > } > return outstr > end > end > > I'm new to ruby so critiques on this code would be useful. Just some stylistic playing around (haven't benchmarked or anything).... Going for the minimalist, no temporary variables look, I came up with: def myjoin [(0...size-1).map {|i| at(i).to_s + yield(i).to_s}, at(-1).to_s].join end And, a somewhat kindler, gentler verion (restoring the temp variable): def myjoin res = "" (0...size-1).each {|i| res += at(i).to_s + yield(i).to_s} res << at(-1).to_s end If you want to use this as #join, and without breaking old code, you can do: class Array alias :oldjoin :join def myjoin(sep=$,) if block_given? res = "" (0...size-1).each {|i| res += at(i).to_s + yield(i).to_s} res << at(-1).to_s else oldjoin(sep) end end end (Also means you don't have to worry about having it added to the core language :-) David -- David Alan Black home: dblack@candle.superlink.net work: blackdav@shu.edu Web: http://pirate.shu.edu/~blackdav