From: Glenn Jackman Date: 2010-03-23T01:45:09+09:00 Subject: Re: Grouping elements of an array At 2010-03-20 08:57PM, "Tanaka Akira" wrote: > 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. I guess that's why Enumerable#each_cons exists, to iterate over a collection and look at the next n consecutive elements. a = [[:A,0],[:B,15],[:C,35],[:D,100],[:E,205],[:F,215],[:G,300]] all = [] current = [a[0][0]] a.each_cons(2) do |m, n| if n[1] - m[1] < 30 current << n[0] else all << current current = [n[0]] end end all << current p all > > 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"]] -- Glenn Jackman Write a wise saying and your name will live forever. -- Anonymous