From: Farrel Lifson Date: 2007-03-06T22:00:15+09:00 Subject: Re: [ ruby-Patches-9055 ] Dynamic Array#join with block On 06/03/07, Nobuyoshi Nakada wrote: > > [1,3,2,4].join(' which is X than '){|sep,a,b| a > b ? sep.sub(/X/,"#{a-b} more") : sep.sub(/X/,"#{b-a} less")} > > which produces > > 1 which is 2 less than 3 which is 1 more than 2 which is 2 less than 4 > > That example seems to fit #inject better. This example can use inject (see bleow) however inject does not handle the recursive 'flattening' functionality that the current implementation of join has when it encounters nested arrays in the general case. For instance [[1,2],[3,4]].join(',') produces "1,2,3,4" and the patch handles things the same way [[1,3],[2,4]].join{|sep,a,b| a > b ? ">" : "<"} will produce "1<3>2<4" If you tried to use inject to do this it would probably get hairy. I implemented the example given using inject and it doesn't look that pretty: ary = [1,3,2,4];idx=1 result = ary.inject("") do |memo,num| memo += "#{num}" + (idx < ary.length ? " which is" + ((num > ary[idx]) ? " #{num - ary[idx]} more" : " #{ary[idx] - num} less") + " than " : "") idx+=1 memo end Trying to deal with possible recursive flattening cases would probably make it look worse. > > The parameters passed into the block are the separator string (sep) > > which is the parameter passed to the join method, and the two elements > > (a,b) between which sep will be inserted. > > It sounds like sep can't be omitted. I guess it might be nice > if ary.join(*seps) yields a, b, *seps. That does sound like a better option. I'll modify the patch to try this although do you think it would be best to keep as just a single sep rather than a seps array so it does not diverge too much from the nature of the original join method. In the previous thread I started on this patch it seems most people don't like passing the sep character in at all but your suggestion seems like a nice approach to me. Thanks, Farrel Farrel