This project is archived and is in readonly mode.
Add in_groups to ActiveSupport::CoreExtensions::Array::Grouping
Reported by Adrian Mugnolo | July 10th, 2008 @ 07:52 AM | in 2.x
This patch provides an accompanying method to in_groups_of, named in_groups.
The purpose of in_groups is to split or iterate over an array in a specified number of groups, whereas in_groups_of offers the same semantics to operate on groups of a specified size.
In other words, the existing method says "divide this into n groups of x elements each", this one says "divide this into x groups of n elements each" (where x is specified, n unknown).
Some code examples:
>> %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3)
=> [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"], ["10", nil, nil]]
>> %w(1 2 3 4 5 6 7 8 9 10).in_groups(3)
=> [["1", "2", "3", "4"], ["5", "6", "7", nil], ["8", "9", "10", nil]]
>> %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, false)
=> [["1", "2", "3", "4"], ["5", "6", "7"], ["8", "9", "10"]]
I've found myself writing this kind of code for views while trying to accomodate several items in n-column layouts:
<% @locations.in_groups(3, false) do |group| %>
<ul style="float: left;">
<%= render :partial => "location", :collection => group %>
</ul>
<% end %>
Note that in_groups will always return the specified number of groups. That remains true even for edge cases like:
>> %w().in_groups(5)
=> [[], [], [], [], []]
>> %w(1).in_groups(5)
=> [["1"], [nil], [nil], [nil], [nil]]
>> %w(1 2 3 4 5).in_groups(5)
=> [["1"], ["2"], ["3"], ["4"], ["5"]]
>> %w(1 2 3 4 5 6).in_groups(5)
=> [["1", "2"], ["3", nil], ["4", nil], ["5", nil], ["6", nil]]
(Thanks to RSL for improving the wording and original examples.)
Comments and changes to this ticket
-
Pratik July 10th, 2008 @ 01:13 AM
- State changed from new to wontfix
I feel it's bit too complex. And extensions like this are a better fit for Rails.root/lib rather than in core.
But if you disagree, please continue the discussion in rails core mailing list.
Thanks.
-
Adrian Mugnolo July 10th, 2008 @ 02:07 AM
Pratik,
I would gladly continue the discussion in the Rails Core mailing list. Still, let me comment on complexity and use cases.
The method interface matches 1:1 the one for in_groups_of -- which in the scope of Rails, lays on the easy side. So use shouldn't be a problem to anyone already using in_groups_of.
Both methods appear as a natural fit. When slicing an array you're usually concerned about either: subarray size (where you would use in_groups_of) or, number of subarrays (where you could use in_groups).
Possible use cases are: view code for n-column layout as in "x accounts/addresses to be splitted in y elements to be floated and rendered as columns"; resource allocation as in "x conference attendees to be arranged along y available rooms"; and many others.
-
RSL July 10th, 2008 @ 03:12 AM
I found the example code in the ticket a little confusing and didn't see the point. Then it clicked in my head that where the existing method says "divide this into n groups of three" this says "divide this into three groups of n". You can see this a little better in:
- Produces four groups of three
>> %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3)
=> [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"], ["10", nil, nil]]
- Produces three groups of four
%w(1 2 3 4 5 6 7 8 9 10).in_groups(3)
=> [["1", "2", "3", "4"], ["5", "6", "7", nil], ["8", "9", "10", nil]]
It seems like a natural converse method to me. :)
-
RSL July 10th, 2008 @ 03:13 AM
Those numbers were supposed to be comments using #. Silly me forgot about formatting.
-
Pratik July 10th, 2008 @ 03:13 AM
- State changed from wontfix to open
-
Adrian Mugnolo July 10th, 2008 @ 06:44 AM
RSL, thanks for coming up with much better wording and code samples! :-)
-
Tarmo Tänav July 10th, 2008 @ 09:03 AM
Looks useful, +1
Though I'd like to point out that if anyone should need a columns-first order (which gives the same fill as in_groups, but the elements are first ordered by row and then column), there are two ways:
- Here 4 is the number of result groups
>> %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(4).transpose
=> [["1", "5", "9"], ["2", "6", "10"], ["3", "7", nil], ["4", "8", nil]]
- Or another way to do the same:
>> y=%w(1 2 3 4 5 6 7 8 9 10).in_groups_of(4)
=> [["1", "2", "3", "4"], ["5", "6", "7", "8"], ["9", "10", nil, nil]]
>> y.shift.zip(*y)
=> [["1", "5", "9"], ["2", "6", "10"], ["3", "7", nil], ["4", "8", nil]]
-
Repository July 15th, 2008 @ 03:05 PM
- State changed from open to resolved
(from [fc89a951933638b051bb1f9e1339ee6ae7c94cda]) Add in_groups to ActiveSupport::CoreExtensions::Array::Grouping. [#579 state:resolved]
Signed-off-by: Pratik Naik
-
Ryan Bigg October 9th, 2010 @ 10:03 PM
- Tag cleared.
- Importance changed from to Low
Automatic cleanup of spam.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>