我有多个可变长度的红宝石阵列,从1到40:
@items是一个典型的数组,长度可以是1到40。例如
@items = [1, 2, 3, 4, 5, 6]
我想将数组随机分成较小的长度为1,2或3的数组,以得到(例如)
的结果@items = [[1, 2],[3],[4,5,6]]
或
@items = [[1],[2, 3],[4],[5,6]]
等
我知道你可以使用@ items.each_slice(3)分割数组...其中3是固定长度。但我想随机将大小可变长度的数组随机分成1,2或3的数组大小...什么是实现这一目标的最佳方法?
答案 0 :(得分:7)
items, @items = @items.dup, []
@items.push(items.shift(rand(1..3))) until items.empty?
答案 1 :(得分:3)
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
您可以将a.size
替换为3
或任何您想要的内容来限制子阵列的大小。
答案 2 :(得分:1)
只是为了哎呀,我以为我会尝试一个纯函数形式,没有变异方法来解决这个问题:
( (0..@items.size)
.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] }
答案 3 :(得分:1)
此解决方案可能使用太多局部变量,但它对输入数组是非破坏性的,并且在阵列窗口最大时是灵活的。
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
另外,我只是想编写一个使用“旋转”方法的解决方案。
答案 4 :(得分:0)
这是另一个功能性解决方案:
( [0]+
(1..a.length-1)
.to_a
.sample(rand(a.length))
.sort+
[a.length]
).each_cons(2).map{|i,j| a[i..j-1]}