I want to define a method that performs the following operation: Given an array: array = [a, b, c, d, e, f, g, h, i] My imaginary method (let's call it nest_by) would produce these results array.nest_by(2) => [[a, b], [c, d], [d, e], [f, g], [h, i]] array.nest_by(3) => [[a, b, c], [d, e, f], [g, h, i]] array.nest_by(4) => [[a, b, c, d], [e, f, g, h], [i, nil, nil, nil]] The contents of the array can be anything (including array's themselves). This is sort of like the rails Array.in_groups_of(n), but uses the array.size to determine the number of elements in each new nested array. Any thoughts? Daniel

on 2007-07-13 22:53

on 2007-07-14 00:00

Ack, what I explained WAS array.in_groups_of(n). What I'm ACTUALLY looking for is: array.nest_by(2) => [[a, b, c, d, e], [f, g, h, i]] array.nest_by(3) => [[a, b, c], [d, e, f], [g, h, i]] array.nest_by(4) => [[a, b, c], [d, e], [f, g], [h, i]] Where nest_by(n) produces n nested arrays. In the case of 2 and 4 when it's not an balanced match, distribute the extras amongst first arrays.

on 2007-07-14 02:00

```
On 7/13/07, danlunde <danlunde@gmail.com> wrote:
> arrays.
This is probably better posted in ruby-talk. Here's a stab, though:
class Array
def nest_by(group_count)
in_groups_of(size / group_count + size %
group_count).collect(&:compact)
end
end
~ j.
```

on 2007-07-14 07:31

On Jul 13, 2:59 pm, danlunde <danlu...@gmail.com> wrote: > Ack, what I explained WAS array.in_groups_of(n). > > What I'm ACTUALLY looking for is: > array.nest_by(2) > => [[a, b, c, d, e], [f, g, h, i]] > array.nest_by(3) > => [[a, b, c], [d, e, f], [g, h, i]] > array.nest_by(4) > => [[a, b, c], [d, e], [f, g], [h, i]] > you could probably golf this, but: require 'enumerator' class Array def nest_by(length_of_out) num_per_element, remainder = self.length.divmod(length_of_out); temp=[] self.reverse.each_slice(num_per_element) { |slice| temp << slice} if remainder>0 temp[-2]+= temp[-1] temp.slice!(-1) end return temp.reverse end end

on 2007-07-16 22:09

Thanks gene.tani, you got me close enough. The only problem with your solution was that if there were 2 remaining elements, I wanted those distributed among the first two nested array, not all in the first array. Here's the finished solution for what I was looking for: class Array def in_n_groups(n) num_per_element, remainder = self.length.divmod(n); orig = self.dup temp = [] until orig.empty? if remainder > 0 temp << orig.slice!(0, num_per_element+1) remainder -= 1 else temp << orig.slice!(0, num_per_element) end end return temp end end array = %w{ a b c d e f g h i j k } array => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"] array.in_n_groups(2) => [["a", "b", "c", "d", "e", "f"], ["g", "h", "i", "j", "k"]] array.in_n_groups(3) => [["a", "b", "c", "d"], ["e", "f", "g", "h"], ["i", "j", "k"]] array.in_n_groups(4) => [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"], ["j", "k"]] Great for distributing long lists of data between balanced table columns. Especially when you only want n columns. Thanks everyone for helping. Daniel