我有一个大型数组,我想将其均匀地分成 n 数组。
我尝试使用each_slice
,但只根据传递给它的数字参数将数组切成小部分。
我该怎么做?
答案 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