Reputation: 2026
Given an array of length N, how I can I equally distribute the elements of the array into another array of arbitrary length?
For instance, I have 3 items in an array and I'd like it distributed evenly across another array of 9 slots.
[1, 2, 3]
should result in (something close to)
[[], [], [1], [], [], [2], [], [], [3]]
However, if I have 9 items to distribute to an array length of 2, it should result in
[[1,2,3,4], [5,6,7,8,9]]
Thanks!
NOTE: The position of the resulting array items could differ according to the algorithm, but the intent is to get some level of uniform distribution. In the first example, the 0th item could be [1]. In the second example, the 0th item could have [1,2,3,4,5].
Upvotes: 0
Views: 140
Reputation: 110725
Here's an easy way to do that:
def distribute(arr, slots)
n = arr.size
a = Array.new(slots) { [] }
arr.each_with_index { |e,i| a[i*slots/n] << e }
a
end
distribute([1,2,3], 9)
#=> [[1], [], [], [2], [], [], [3], [], []]
distribute([*(1..9)], 2)
#=> [[1, 2, 3, 4, 5], [6, 7, 8, 9]]
You could change the distributions that result by modifying i*slots/n
.
Upvotes: 2
Reputation: 15967
So there are two totally different use cases here, one where you have to build an array of length n, the other where you need to split into an array of length n.
This feels like a homework assignment but I don't really have enough off these two use cases to see a pattern (unless I'm missing something huge).
Test cases:
it 'splits on n vals' do
arr = [1,2,3]
expect(chunk(arr, 9)).to eq [[], [], [1], [], [], [2], [], [], [3]]
end
it 'splits on n vals' do
arr = [1,2,3,4,5,6,7,8,9]
expect(chunk(arr,2)).to eq [[1,2,3,4,5],[6,7,8,9]]
end
Code:
def chunk(arr, num)
if num < arr.length
return arr.each_slice( (arr.size/num.to_f).round).to_a
end
array = []
len = arr.length
(0..num).each do |i|
if (i % len == 0) && i != 0
array[i-1] = [arr.first]
array[i] = []
arr.shift
else
array[i] = []
end
end
array.pop
array
end
Upvotes: 1