Hi all,
Here’s another contribution for anyone interested.
In Railscast episode 28, Ryan B. showed us in_groups_of which
allows you to group array members such as
list = [1, 2, 3, 4, 5, 6, 7]
=> [1, 2, 3, 4, 5, 6, 7]list.in_groups_of(3)
=> [[1, 2, 3], [4, 5, 6], [7, nil, nil]]
This allows you to iterate over the groups and, for example, display
a list of things in a tabular format.
1 2 3
4 5 6
7
I thought this was pretty cool, but wanted to go vertically down the
column first, instead of horizontally
1 4 7
2 5
3 6
Well, last night I decided I really needed this vertical grouping,
so …
module ActiveSupport
module CoreExtensions
module Array
module Grouping
def in_vertical_groups_of(number, fill_with = nil, &block)
collection = dup
per_column = (collection.size.to_f / number).ceil
new_collection = []
(0...per_column).each do |i|
(0...number).each do |multiplier|
offset = i + (per_column * multiplier)
new_collection << (offset < collection.size ? collection
[offset] : (fill_with != false ? fill_with : nil))
end
end
return new_collection.in_groups_of(number, fill_with, &block)
end
end
end
end
end
All this really does is reorders the array then calls in_groups_of.
The only caveat (that I’m aware of right now), is you have to fill
“empty” spots in the array or the column spanning won’t work right.
So in a case where could do this
list.in_groups_of(3, false)
=> [[1, 2, 3], [4, 5, 6], [7]]
in_vertical_groups_of will return
list.in_vertical_groups_of(3, false)
=> [[1, 4, 7], [2, 5, nil], [3, 6, nil]]
The ultimate end of this is
@members = Member.find(:all)
…
and then in the _member partial
or whatever your requirements are. This will display a list of
members in three columns, top to bottom, left to right, like a phone
book.
If anyone discovers something I did poorly or just plain missed,
please let me know. Oh, and I have not done any testing/experimenting
with passing a block. But since that is just getting passed along, I
don’t see why it wouldn’t work.
Peace,
Phillip