Reputation: 115
I have multiple arrays in ruby of variable length from 1 to 40 :
@items is a typical array which could be anywhere from 1 to 40 in length. eg
@items = [1, 2, 3, 4, 5, 6]
I want to randomly split the array into smaller arrays of lengths either 1, 2 or 3 to give a result of (for example)
@items = [[1, 2],[3],[4,5,6]]
or
@items = [[1],[2, 3],[4],[5,6]]
etc
I know you can split the array using @items.each_slice(3)... where 3 is a fixed length. But i want to randomly split large arrays of variable length into array sizes of 1,2 or 3 randomly... Whats the best way to achieve this?
Upvotes: 4
Views: 905
Reputation: 20398
Just for yucks, I thought I'd try a pure functional form with no mutating methods for this problem:
( ([email protected])
.inject([0]) { |m,_| m + [m.last + 1 + rand(3)] }
.take_while { |i| i < @items.size } + [@items.size] ).
each_cons(2).
map { |s,e| @items[s...e] }
Upvotes: 1
Reputation: 1808
This solution maybe uses too many local variables, but it is non-destructive to the input array and flexible on array window maximum.
def rotateAndTake inputArray, windowSize
rotator, returnArray, breaker = 0, [], true
while breaker do
window = rand(windowSize)+1
if(rotator + window > inputArray.length) then
window = inputArray.length - rotator
breaker = false
end
returnArray << inputArray.rotate(rotator).take(window) if window > 0
rotator += window
end
returnArray
end
Also, I just wanted to write a solution that used the "rotate" method.
Upvotes: 1
Reputation: 44090
Here's another functional solution:
( [0]+
(1..a.length-1)
.to_a
.sample(rand(a.length))
.sort+
[a.length]
).each_cons(2).map{|i,j| a[i..j-1]}
Upvotes: 0
Reputation: 168199
items, @items = @items.dup, []
@items.push(items.shift(rand(1..3))) until items.empty?
Upvotes: 7
Reputation: 15010
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = []
until a.empty?
b << a.shift((1..a.size).to_a.sample)
end
# b => [[1, 2], [3, 4, 5, 6, 7], [8, 9], [10]]
# change everytime though
You can limit the sub arrays size by replacing the a.size
with 3
or anything you want.
Upvotes: 3