如何将数组拆分为n等于或接近相等的数组?

时间:2016-01-05 19:48:23

标签: arrays ruby

我有一个大型数组,我想将其均匀地分成 n 数组。

  • 我有一个包含100个元素的数组。我想将它平均分成4个数组。这将给我4个数组,每个数组包含25个元素。
  • 我有一个包含100个元素的数组。我想将它平均分成3个数组。由于我无法将其均匀地分割成子数组,因此我需要类似于3个33个元素的数组和一个包含34个元素的数组。
  • 我有一个包含2个元素的数组。我想将它平均分成4个数组。由于我无法均匀地拆分它并且某些数组将是空的,所以我想要2个1个数组和2个空数组的数组。

我尝试使用each_slice,但只根据传递给它的数字参数将数组切成小部分。

我该怎么做?

3 个答案:

答案 0 :(得分:7)

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

a.group_by.with_index{|_, i| i % 2}.values
# => [[1, 3, 5, 7, 9], [2, 4, 6, 8, 10]]

a.group_by.with_index{|_, i| i % 3}.values
# => [[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]]

a.group_by.with_index{|_, i| i % 4}.values
# => [[1, 5, 9], [2, 6, 10], [3, 7], [4, 8]]

a.group_by.with_index{|_, i| i % 5}.values
# => [[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]

a.group_by.with_index{|_, i| i % 6}.values
# => [[1, 7], [2, 8], [3, 9], [4, 10], [5], [6]]

答案 1 :(得分:1)

如果您不需要保留元素的连续性,则@sawa当前的最高答案很有用。如果邻接很重要,这是一个解决方案。

这个问题的发生与线描算法和线性插值相似。我们基本上希望将原始索引缩放到新的索引范围。换句话说,我们将从原点开始绘制一条斜率为new_count / old_count 的线。

如果序列中较大的组位于什么位置都没有关系,并且如果没有足够的项目,那么最后不需要空组,那么可以使用Ruby的{{3} }方法:

# This can be copy/pasted into Pry (thus the `self.`)
def self.groups(enum, numgroups)
  enum.chunk.with_index { |_, idx|
    (idx * numgroups / enum.count)
  }.map(&:last)
end

#chunk方法返回带有块的索引,因此.map(&:last)仅给我们提供了组。如果速度很重要,这不是最有效的方法,但可以完成工作。

一些示例运行:

group2(1..13, 7)
# => [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13]]

group2(1..13, 3)
# => [[1, 2, 3, 4, 5], [6, 7, 8, 9], [10, 11, 12, 13]]

group2(1..100, 7).to_a
# => [[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, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43],
 [44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58],
 [59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72],
 [73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86],
 [87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]]

您可能已经注意到较长和较短的块是混合在一起的。可以设计一个版本,该版本首先计算长度,对长度进行排序,然后返回这些排序后的大小的块。

答案 2 :(得分:0)

@sawa的回答很出色。

但是我为统一分发编写了自己的函数,而b却没有提供。

我的简单函数可以均匀分布数组的元素:

:put

让我们同时测试它们

"bp

result_array_1(group_by):

def split_array_to_parts(array, parts_number)
  part_size = array.size * 1.0 / parts_number
  partitioned_elements_count = 0

  parts = []
  parts_number.times do |index|
    part_length = (part_size * (index+1)).round - partitioned_elements_count
    parts << array.slice(partitioned_elements_count, part_length)
    partitioned_elements_count += part_length
  end

  parts
end

result_array_2(我的函数begin [11,15,17,21,23].each do |count| array = Array.new(count, 0) result_array_1 = array.group_by.with_index{|_, i| i % 10}.values result_array_2 = split_array_to_parts(array, 10) res.map { |inner_array| print "#{inner_array.count} " } print "\n" end end ):

group_by.with_index

欢迎您检查并比较类似的解决方案:

How to split (chunk) a Ruby array into parts of X elements? - duplicate

Splitting an array into equal parts in ruby - duplicate

How to chunk an array in Ruby