From: Julian Leviston Date: 2008-03-31T12:49:20+09:00 Subject: Re: inject's pathological case... ...or you could do it like this: def collect_repeats_inject(list) return list unless list.respond_to?(:inject) collected_hash = list.inject({}) do |collected_repeats, item| ( collected_hash[item] ||= [] ) << item collected_hash end collected_hash.values end On 30/03/2008, at 8:55 PM, William James wrote: > On Mar 30, 12:27 am, 7stud -- wrote: >> Oh, yeah: >> >> $ ruby -v >> ruby 1.8.2 (2004-12-25) [universal-darwin8.0] >> >> By the way, using inject() is inefficient--not to mention confusing. >> You might as well pretend it doesn't exist. > > There is some truth to that. > > > def collect_repeats_inject list > return [] if [] == list > list[1..-1].inject([[ list.first ]]){|a,e| > if a[-1][0] == e > a[-1] << e > else > a << [e] > end > a > }.reject{|lst| lst.size < 2 } > end > > def collect_repeats list > accum = [ [ list.shift ] ] > list.each{|e| > if accum[-1][0] == e > accum[-1] << e > else > accum << [e] > end } > accum.reject{|lst| lst.size < 2 } > end > > p collect_repeats( %w(0 1 1 2 3 3 3 3 4 5 5 6) ) > p collect_repeats( [] ) > p collect_repeats_inject( %w(0 1 1 2 3 3 3 3 4 5 5 6) ) > p collect_repeats_inject( [] ) > > the_list = %w(0 1 1 2 3 3 3 3 3 3 3 3 4 5 5 6 7 8 8 9 9 9) > > t = Time.now > 9999.times{ collect_repeats_inject( the_list )} > p Time.now - t > t = Time.now > 9999.times{ collect_repeats( the_list )} > p Time.now - t > > --- output --- > [["1", "1"], ["3", "3", "3", "3"], ["5", "5"]] > [] > [["1", "1"], ["3", "3", "3", "3"], ["5", "5"]] > [] > 2.694 > 0.16 > > > And the version without inject is shorter and > clearer. >