ruby / splitting数组到列中

时间:2015-12-14 01:02:27

标签: ruby-on-rails arrays ruby

我可以发现使用正确的命名,但到目前为止没有任何突然出现。我会考虑将数组拆分成列。

意思是,拥有[0,1,2,3,4,5,6,7,9],我希望有4个数组(4列):

[ [0,4,9], [1,5], [2,6], [3,7] ]

实际上,我会研究迭代一个活动的记录数组,在4个不同的html列中显示它们(它们是图像记录),同时从左到右保持它们的顺序

6 个答案:

答案 0 :(得分:12)

Rails解决方案

在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是一个添加到Array类的酷rails方法,其行为与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并且不关心它的用户,那就去看看弹性盒子吧。有一天它可能成为一个标准,并且已经可以在许多页面上看到。

答案 1 :(得分:4)

我有一个简短的解决方案: - )

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: Arrays by Example上发布了一篇关于视觉资源的博文。

答案 2 :(得分:2)

这应该可以解决问题:

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

答案 3 :(得分:1)

或通过使用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]

fyi,不完全是一个数组数组,但需要深入研究。

答案 4 :(得分:1)

我假设如果数组的大小没有均匀地除以<div id="load_tapGame"></div> <div id="menu"> <img style="position: absolute; top: 2150px; left: 185px; z-index: 2" src="library/image/tapAStarButtonCloud.png" /> <div class="button"> <button id="tapButton" class="buttonProperty"> <img src="library/image/tapButton.png" /> </button> </div> </div>,那么第一个如此多的切片数组将具有相同的大小,并且每个切片数组的每个剩余切片的数量都多于一个阵列。 您可以通过以下几种方式实现这一目标。

4

计算具有额外元素的数组数

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]] 

答案 5 :(得分:1)

纯Ruby解决方案。

def split(n, arr)
  arr.each_with_index.reduce(Array.new(n) { [] }) do |a, (e, i)|
    a[i%n] << e
    a
  end
end

更新:作为Cary建议的oneliner。它使用with_object()代替reduce()并在使用时懒惰地初始化子数组。

def split(n, arr)
  arr.each_with_index.with_object([]) { |(e, i), a| (a[i%n] ||= []) << e }
end