可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This question already has an answer here:
-
How to chunk an array in Ruby
2 answers
I need a way to split an array in to a bunch of arrays within another array of equal size. Anyone have any method of doing this?
For instance
a = [0, 1, 2, 3, 4, 5, 6, 7]
a.method_i_need(3)
a.inspect
=> [[0,1,2], [3,4,5], [6,7]]
回答1:
You're looking for 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]]
回答2:
Perhaps I'm misreading the question since the other answer is already accepted, but it sounded like you wanted to split the array in to 3 equal groups, regardless of the size of each group, rather than split it into N groups of 3 as the previous answers do. If that's what you're looking for, Rails (ActiveSupport) also has a method called 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]]
I don't think there is a ruby equivalent, however, you can get roughly the same results by adding this simple method:
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]]
The only difference (as you can see) is that this won't spread the "empty space" across all the groups; every group but the last is equal in size, and the last group always holds the remainder plus all the "empty space".
Update:
As @rimsky astutely pointed out, the above method will not always result in the correct number of groups (sometimes it will create multiple "empty groups" at the end, and leave them out). Here's an updated version, pared down from ActiveSupport's definition which spreads the extras out to fill the requested number of groups.
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
回答3:
Try
a.in_groups_of(3,false)
It will do your job
回答4:
As mltsy wrote, in_groups(n, false)
should do the job.
I just wanted to add a small trick to get the right balance
my_array.in_group(my_array.size.quo(max_size).ceil, false)
.
Here is an example to illustrate that trick:
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]]
回答5:
This needs some better cleverness to smear out the extra pieces, but it's a reasonable start.
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]]