我需要一种方法将数组拆分为另一个大小相等的数组中的一堆数组。有人有任何方法吗?
例如
a = [0, 1, 2, 3, 4, 5, 6, 7]
a.method_i_need(3)
a.inspect
=> [[0,1,2], [3,4,5], [6,7]]
答案 0 :(得分:106)
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]]
答案 1 :(得分:97)
也许我误解了这个问题,因为另一个答案已被接受,但听起来你想将数组分成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]]
我认为没有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]]
唯一的区别(如你所见)是这不会在所有群体中传播“空白空间”;每一组但最后一组的大小相等,最后一组总是保留余数加上所有“空格”。
<强>更新强> 正如@rimsky精明地指出的那样,上述方法并不总是会产生正确数量的组(有时它会在最后创建多个“空组”,并将它们排除在外)。这是一个更新版本,从ActiveSupport's definition开始减少,将额外内容分散开来以填充所请求的群组数量。
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
答案 2 :(得分:15)
尝试
a.in_groups_of(3,false)
它会完成你的工作
答案 3 :(得分:1)
正如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]]
答案 4 :(得分:1)
这需要一些更好的聪明才能抹掉额外的碎片,但这是一个合理的开始。
def i_need(bits, r)
c = r.count
(1..bits - 1).map { |i| r.shift((c + i) * 1.0 / bits ) } + [r]
end
> i_need(2, [1, 3, 5, 7, 2, 4, 6, 8])
=> [[1, 3, 5, 7], [2, 4, 6, 8]]
> i_need(3, [1, 3, 5, 7, 2, 4, 6, 8])
=> [[1, 3, 5], [7, 2, 4], [6, 8]]
> i_need(5, [1, 3, 5, 7, 2, 4, 6, 8])
=> [[1, 3], [5, 7], [2, 4], [6], [8]]