即,将
[0,1,2,3,4,5,6,7,9]
拆分为 4 个数组(4 列):[ [0,4,9], [1,5], [2,6], [3,7] ]
实际上,我会遍历 active record 数组,在 4 个不同的 HTML 列中显示它们(它们是图片记录),同时保持其从左到右的顺序。[0,1,2,3,4,5,6,7,9]
拆分为 4 个数组(4 列):[ [0,4,9], [1,5], [2,6], [3,7] ]
实际上,我会遍历 active record 数组,在 4 个不同的 HTML 列中显示它们(它们是图片记录),同时保持其从左到右的顺序。在 Rails 中,您可以简单地执行以下操作:
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
是一个很酷的Rails方法,添加到了Array类中,它的行为与each_slice
非常相似,不同之处在于它保证所有数组具有相同的大小。这里很重要,因此我们可以稍后使用transpose
方法。该方法返回您的行的数组。
现在,transpose
- 另一个值得知道的酷方法。它期望一个数组数组,并且所有内部数组的长度必须相同(因此实际上代表一个矩形矩阵)。它的作用是返回目标数组中的列的数组。
现在我们需要除去nils(除非它们不打扰你),所以我们对每个列运行compact
,然后我们就得到了您想要的东西。
我们没有in_groups_of
,所以我们需要在没有它的情况下实现相同的行为:
ary.each_slice(4).map {|a| a.fill nil, a.size, 4 - a.size}.transpose.map(&:compact)
实际上,我会考虑遍历一个活动记录数组,并在4个不同的html列中显示它们(它们是图像记录),同时保持它们从左到右的顺序。
除非数据是表格数据,否则您不应使用表格来显示数据。图像不是表格数据,这意味着特定图像在某个列/行中的位置完全无关紧要。总是有更好的方法来解决这个问题。
对于你的情况,我建议使用纯CSS解决方案(haml):
%ul.images
- @images.each do |i|
%li= image_tag i.iamge_url # or sth
然后在你的 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
}
}
这种模型的主要优点在于您可以根据媒体查询使列数成为变量,因此根据用户屏幕尺寸显示不同数量的图像(对于移动设备非常重要)。
如果您想冒险一些,并且您讨厌IE并且不关心它的用户,请去尝试一下flex-boxes。有一天它可能会成为标准,并且已经出现在许多页面上。
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]]
我已经发布了一篇关于Ruby中数组的博客文章,该文章可以作为一个视觉资源,您可以通过链接查看。
input = [0,1,2,3,4,5,6,7,8,9]
max_columns = 4
input.each_with_index.with_object([]) do | (val, index), output|
i = index % max_columns
(output[i] ||= []).push(val)
end
input.each_with_index.with_object([]) do |(val, index), output|
。 - Cary Swovelandwith_object
方法,看起来非常有用! - hbejgel或者通过将您的大数组切片成较小的数组 SLICE。
input = Array(1 .. 33)
output = input.each_slice(4).to_a
output.each do |x| puts "#{x}"
end
输出:
[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]
提供信息,不完全是一个数组的数组,但值得关注。
arr = [1,2,3,4,5,6,7,8,9]
def split_it(n, arr)
std_arr_size, nbr_bonus_arrays = arr.size.divmod(n)
nbr_bonus_elements = nbr_bonus_arrays * (std_arr_size + 1)
arr[0...nbr_bonus_elements].each_slice(std_arr_size+1).to_a +
arr[nbr_bonus_elements..-1].each_slice(std_arr_size).to_a
end
split_it(1, arr) #=> [[1, 2, 3, 4, 5, 6, 7, 8, 9]]
split_it(2, arr) #=> [[1, 2, 3, 4, 5], [6, 7, 8, 9]]
split_it(3, arr) #=> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
split_it(4, arr) #=> [[1, 2, 3], [4, 5], [6, 7], [8, 9]]
split_it(5, arr) #=> [[1, 2], [3, 4], [5, 6], [7, 8], [9]]
split_it(6, arr) #=> [[1, 2], [3, 4], [5, 6], [7], [8], [9]]
split_it(7, arr) #=> [[1, 2], [3, 4], [5], [6], [7], [8], [9]]
split_it(8, arr) #=> [[1, 2], [3], [4], [5], [6], [7], [8], [9]]
split_it(9, arr) #=> [[1], [2], [3], [4], [5], [6], [7], [8], [9]]
def split_it(n, arr)
return [arr] if n==1
m = (arr.size.to_f/n).ceil
[arr.first(m)] + split_it(n-1, arr[m..-1])
end
split_it(1, arr) #=> [[1, 2, 3, 4, 5, 6, 7, 8, 9]]
split_it(2, arr) #=> [[1, 2, 3, 4, 5], [6, 7, 8, 9]]
split_it(3, arr) #=> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
split_it(4, arr) #=> [[1, 2, 3], [4, 5], [6, 7], [8, 9]]
split_it(5, arr) #=> [[1, 2], [3, 4], [5, 6], [7, 8], [9]]
split_it(6, arr) #=> [[1, 2], [3, 4], [5, 6], [7], [8], [9]]
split_it(7, arr) #=> [[1, 2], [3, 4], [5], [6], [7], [8], [9]]
split_it(8, arr) #=> [[1, 2], [3], [4], [5], [6], [7], [8], [9]]
split_it(9, arr) #=> [[1], [2], [3], [4], [5], [6], [7], [8], [9]]
def split(n, arr)
arr.each_with_index.reduce(Array.new(n) { [] }) do |a, (e, i)|
a[i%n] << e
a
end
end
更新: Cary建议使用一行代码,它使用with_object()
代替reduce()
,并在使用时惰性地初始化子数组。
def split(n, arr)
arr.each_with_index.with_object([]) { |(e, i), a| (a[i%n] ||= []) << e }
end
arr.each_with_index.with_object([]) { |(e,i),a| (a[i%n] ||= []) << e }
。 - Cary Swovelandreduce()
时,避免了额外的语句a
来返回累积对象。下次会采纳这个建议。 - sschmeck