From: William James Date: 2006-07-30T03:05:10+09:00 Subject: Re: how to split an array in sub arrays of the same length William James wrote: > bbiker wrote: > > bbiker wrote: > > > I believe the OP asked how to split an array in "x" sub arrays of equal > > > length. > > > To me, it appears that the response show how to partition an array into > > > sub arrays of "y" elements. > > > > > > The following method does what the OP asked for, as far as I read it. > > > > > > class Array > > > def split(n, b=[], d=[]) > > > ######################################################################### > > > # evenly split array 'a' into 'n' sub arrays > > > ######################################################################### > > > if self.size == 0 or n <= 0 > > > b = nil > > > elsif n == 1 > > > b = *self > > > else > > > # determine how many elements of the array should go in each sub > > > arrays > > > buckets = n > > > length = self.size > > > while buckets > 0 > > > elements = length / buckets + (length % buckets > 0 ? 1 : 0) > > > d << elements > > > length -= elements > > > buckets -= 1 > > > end > > > # p d > > > > > > # evenly distribute array elements into an array with 'n' sub arrays > > > start = 0 # start > > > 0.upto(n-1) do |idx| > > > len = d[idx] > > > b[idx] = *self.slice(start,len) > > > start += len > > > end > > > end > > > b > > > end > > > end > > > > Sorry, but I pressed the Post message button too soon. > > > > c = > > [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23].split(5) > > => > > > > [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, > > 19], [20, 21, 22, 23]] > > > > Note that the first 3 sub arrays contain 5 elements and the last 2 sub > > arrays contain 4 elements. > > > > I am a Ruby newbie and would appreciate a critique on the method I > > posted. > > > > Thank You > > class Array > def split n > count , fat_ones = self.size / n , self.size % n > self.inject( [[]] ){ |a,e| > a.last.size < count + ( a.size <= fat_ones ? 1 : 0 ) ? > a.last << e : a << [e] ; a } > end > end > > a = (1..23).to_a > p a.split(5) > p a Perhaps faster: class Array def split n count , fat_ones = self.size / n , self.size % n cp, out = self.dup, [] out << cp. slice!(0, count + (out.size < fat_ones ? 1 : 0 )) while cp!=[] out end end