1 2 3 4 5 6 7 8 9 10
<% col_size = (friends.size/4.0).ceil %> <% friends.in_groups_of(col_size, false) do |group| %> <div class=‘list‘> <ul> <% group.each do |friend| %> <li><%= display friend %></li> <% end %> </ul> </div> <% end %>
Refactorings
No refactoring yet !
Jeremy Weiskotten
November 28, 2007, November 28, 2007 16:21, permalink
You seem to be specifying three different expected results for an array of 9 friends. Which is correct?
[1,2,3],[4,5,6],[7,8,9],[]
[1,2,3],[4,5],[6,7],[8,9]
[1,2,3],[4,5,6],[7,8],[9,10]
Any of these should be pretty easy to do, but the requirements aren't clear.
Jason Dew
November 28, 2007, November 28, 2007 17:23, permalink
here's my first shot at it
code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
class Array def in_uniform_groups_of(group_count) answer = Array.new index = 0 self.class.uniform_partition_sizes(self.size, group_count).each do |size| answer << self.slice( index, size ) index += size end answer end def self.uniform_partition_sizes(size, partitions) answer = Array.new( partitions, size / partitions ) index = 0 total = (size / partitions) * partitions while total < size answer[index] += 1 index = (index + 1) % partitions total += 1 end answer end end puts (1..9).to_a.in_uniform_groups_of(4).inspect puts (1..10).to_a.in_uniform_groups_of(4).inspect
JohnnyBusca
November 28, 2007, November 28, 2007 20:57, permalink
The example shown above returned:
9 friends: [1,2,3],[4,5,6],[7,8,9],[]
10 friends: [1,2,3],[4,5,6],[7,8,9],[10]
and I wanted the following:
9 friends: [1,2,3],[4,5],[6,7],[8,9]
10 friends: [1,2,3],[4,5,6],[7,8],[9,10]
In the meantime I've come up with an helper method which works as a wanted.
1 2 3 4 5 6 7
def split_in_groups(values, cols=4) cols.downto(1) do |col| group_size = (values.size / col.to_f).ceil - 1 yield(group = values[0..group_size]) values -= group end end
Jeremy Weiskotten
November 28, 2007, November 28, 2007 22:20, permalink
I misread your original post. Now I understand what you're expecting.
I'll post something in a bit.
Jeremy Weiskotten
November 28, 2007, November 28, 2007 23:11, permalink
I've added a columnize method to Array. The unit test confirms that 1-9 and 1-10 in 4 columns behave the way you expect. I think this will work for any other combo. I'm not sure what the behavior should be if there aren't enough items in the array to populate the given number of columns -- in this implementation the method will return an array with only as many columns as necessary, but it would be pretty easy to have it return empty or nil columns instead.
This should be more efficient than the helper you posted above, because it's not resizing the (potentially large) array as you do with "values -= group". It does all of its work with some simple arithmetic to calculate offset and column size for slicing out of the source array.
Please rate this refactoring if it helps!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
class Array def columnize(n_columns) columns = [] remaining_size = self.size n_columns.times do |column_idx| column_size = (remaining_size.to_f / (n_columns - column_idx)).ceil break if column_size == 0 columns << self.slice(self.size - remaining_size, column_size) remaining_size -= column_size end columns end end class ColumnizeTest < Test::Unit::TestCase def test_columnize_9 assert_equal [[1,2,3],[4,5],[6,7],[8,9]], (1..9).to_a.columnize(4) end def test_columnize_10 assert_equal [[1,2,3],[4,5,6],[7,8],[9,10]], (1..10).to_a.columnize(4) end end
I would like to have a piece of code which splits an array in a fixed number of groups.
On a page I have 4 colums. I want to display an array of friends in 4 columns.
On http://skwpspace.com/2006/09/27/multi-column-lists-using-in_groups_of/ I found an example with in_groups_of, but this doesn't do the trick.
An array with 9 friends will result in 3 groups of 3 friends each. [1,2,3],[4,5,6],[7,8,9],[]
and 10 friends will result in 4 groups [1,2,3],[4,5,6],[7,8,9],[10]
And I wanted the results to be: 9: [1,2,3],[4,5],[6,7],[8,9] and [1,2,3],[4,5,6],[7,8],[9,10]
Is there an easy why of getting this?