将数组拆分为红宝石中的相等部分

Red*_*Red 54 ruby arrays ruby-on-rails ruby-1.8.7

我需要一种方法将数组拆分为另一个大小相等的数组中的一堆数组.有人有任何方法吗?

例如

a = [0, 1, 2, 3, 4, 5, 6, 7]
a.method_i_need(3)
a.inspect
    => [[0,1,2], [3,4,5], [6,7]]
Run Code Online (Sandbox Code Playgroud)

Jos*_*eek 110

您正在寻找 Enumerable#each_slice

a = [0, 1, 2, 3, 4, 5, 6, 7]
a.each_slice(3) # => #<Enumerator: [0, 1, 2, 3, 4, 5, 6, 7]:each_slice(3)>
a.each_slice(3).to_a # => [[0, 1, 2], [3, 4, 5], [6, 7]]
Run Code Online (Sandbox Code Playgroud)

  • 只是一张纸条.这会将数组拆分为大小为3的组,而不是3个大小相等的组. (19认同)

mlt*_*tsy 101

也许我误解了这个问题,因为另一个答案已经被接受了,但听起来你想要将数组分成3个相等的组,无论每个组的大小如何,而不是将它分成N组,每组3个.以前的答案.如果这就是你要找的东西,Rails(ActiveSupport)也有一个名为in_groups的方法:

a = [0,1,2,3,4,5,6]
a.in_groups(2) # => [[0,1,2,3],[4,5,6,nil]]
a.in_groups(3, false) # => [[0,1,2],[3,4], [5,6]]
Run Code Online (Sandbox Code Playgroud)

我不认为有一个ruby等价物,但是,你可以通过添加这个简单的方法得到大致相同的结果:

class Array; def in_groups(num_groups)
  return [] if num_groups == 0
  slice_size = (self.size/Float(num_groups)).ceil
  groups = self.each_slice(slice_size).to_a
end; end

a.in_groups(3) # => [[0,1,2], [3,4,5], [6]]
Run Code Online (Sandbox Code Playgroud)

唯一的区别(正如你所看到的)是,这不会在所有群体中传播"空白空间"; 每个组但最后一个组的大小相等,最后一组始终保留余数加上所有"空格".

更新: 正如@rimsky精明地指出的那样,上述方法并不总是会产生正确数量的组(有时它会在最后创建多个"空组",并将它们排除在外).这是一个更新版本,从ActiveSupport的定义减去,它将额外内容传播出去以填充所请求的组数.

def in_groups(number)
  group_size = size / number
  leftovers = size % number

  groups = []
  start = 0
  number.times do |index|
    length = group_size + (leftovers > 0 && leftovers > index ? 1 : 0)
    groups << slice(start, length)
    start += length
  end

  groups
end
Run Code Online (Sandbox Code Playgroud)

  • 我知道这是一个很老的帖子,但对于那些正在考虑上面的红宝石的人来说,它并不完全正确.如果您尝试将20个元素的数组拆分为11个组,则最终只会有10个组.slice_size将为2,而20可被2整除. (4认同)

Par*_*ngh 16

尝试

a.in_groups_of(3,false)
Run Code Online (Sandbox Code Playgroud)

它会完成你的工作

  • 请注意,[`in_groups_of`](http://rails.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Array/Grouping.html)特定于Rails(或更确切地说,ActiveSupport),而@ Joshua的答案在Ruby中可用.仍然,+1提供工作解决方案. (14认同)

小智 5

正如 mltsy 所写,in_groups(n, false)应该完成这项工作。

我只是想添加一个小技巧来获得适当的平衡 my_array.in_group(my_array.size.quo(max_size).ceil, false)

下面是一个例子来说明这个技巧:

a = (0..8).to_a
a.in_groups(4, false) => [[0, 1, 2], [3, 4], [5, 6], [7, 8]]
a.in_groups(a.size.quo(4).ceil, false) => [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
Run Code Online (Sandbox Code Playgroud)