I could've found out using the right naming, but so far nothing popped up. I'd look into splitting an array into columns.
Meaning, having [0,1,2,3,4,5,6,7,9]
, I'd like to have 4 arrays (4 columns) :
[ [0,4,9], [1,5], [2,6], [3,7] ]
Practically, I'd look into iterating over an active record array, displaying those (they're images records) in 4 different html columns, while maintaining their order from left to right
In rails, you can simply do:
ary = [0,1,2,3,4,5,6,7,8,9]
ary.in_groups_of(4).transpose.map(&:compact)
#=> [[0, 4, 8], [1, 5, 9], [2, 6], [3, 7]]
in_groups_of
is a cool rails method added to Array class, which behaves very similar to each_slice
, with the difference being that it guarantees all the arrays to be the same size. It is important here so we can use transpose
later on. This method returns an array of your rows.
Now, transpose
- another cool method worth knowing. It expects an array of arrays, and all inner arrays must be the same length (so in fact this represents a rectangular matrix). What it does - it returns an array of columns in target array.
Now we need to get rid of nils (unless they don't bother you), so we run compact
on each of the columns and we have exactly what you wanted.
We don't have in_groups_of
so we need to implement same behaviour without it:
ary.each_slice(4).map {|a| a.fill nil, a.size, 4 - a.size}.transpose.map(&:compact)
Practically, I'd look into iterating over an active record array, displaying those (they're images records) in 4 different html columns, while maintaining their order from left to right
You should never use tables to display your data unless it is a tabular data. Images are not tabular data, meaning that the location of that particular image at given column/row is completely irrelevant. There always is a better way to do this.
In your case, I would suggest pure CSS solution (haml):
%ul.images
- @images.each do |i|
%li= image_tag i.iamge_url # or sth
Then in your css (scss):
ul.images {
width: 100%;
font-size: 0; # remove whitespace between li elements
li {
display: inline-block;
width: 25%; # forcing 25% without whitespaces guarantees 4 column
}
}
Main advantage of this model is that you can make the number of column dependent on media queries, so display different number of images per row depending on your user screen size (important for mobiles).
If you feel more adventurous and you hate IE and don't care for it's users, go and check out flex-boxes as well. One day it might become a standard and can be seen on many pages already.
I have a short solution :-)
x = [0, 1, 2, 3, 4, 5, 6, 7, 9]
x.group_by.with_index {|_,index| index % 4 }.values
# => [[0, 4, 9], [1, 5], [2, 6], [3, 7]]
I have posted a blog post on Ruby: Arrays by Example for a visual resource.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With