From: Tanaka Akira Date: 2010-03-21T09:57:02+09:00 Subject: Re: Grouping elements of an array 2010/3/19 Steve Wilhelm : > Example (second column is timestamp in seconds starting from zero). > > A 0 > B 15 > C 35 > D 100 > E 205 > F 215 > G 300 > > would result in > > [[A, B, C], [D], [E, F], [G]] I think this kind of problems which slices consecutive elements in an array is not well supported in Ruby. Enumerable#each_slice is not usable because it slices for each fixed number of elements. Ruby 1.9.2 has Enumerable#slice_before and it is usable but not so elegant because it needs to maintain previous element. % ruby -e ' a = [ ["A", 0], ["B", 15], ["C", 35], ["D", 100], ["E", 205], ["F", 215], ["G", 300] ] prev = nil p a.slice_before {|s,t| tmp, prev = prev, t tmp && (t-tmp) > 30 }.map {|es| es.map {|s,t| s } } ' [["A", "B", "C"], ["D"], ["E", "F"], ["G"]] We may need Enumerable#slice_between. % ruby -e ' module Enumerable def slice_between(&b) Enumerator.new {|y| first = true buf = [] prev = nil self.each {|elt| if first first = false buf << elt prev = elt else if b.call(prev, elt) y << buf buf = [elt] else buf << elt end prev = elt end } if !buf.empty? y << buf end } end end a = [ ["A", 0], ["B", 15], ["C", 35], ["D", 100], ["E", 205], ["F", 215], ["G", 300] ] p a.slice_between {|(s1,t1),(s2,t2)| (t2-t1) < 30 }.map {|es| es.map {|s,t| s } } ' [["A"], ["B"], ["C", "D", "E"], ["F", "G"]] -- Tanaka Akira