什么是将ruby中的数组拆分为多个随机大小的较小数组的最佳方法

时间:2022-10-23 12:18:08

I have multiple arrays in ruby of variable length from 1 to 40 :

我有多个可变长度为1到40的ruby数组:

@items is a typical array which could be anywhere from 1 to 40 in length. eg

@items是一个典型的数组,长度可以是1到40。例如

@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)

我想随机将数组拆分成较小的长度为1,2或3的数组,以得到(例如)的结果

@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?

我知道你可以使用@ items.each_slice(3)分割数组......其中3是固定长度。但我想随机将大小可变长度的数组随机分成1,2或3的数组大小...什么是实现这一目标的最佳方法?

5 个解决方案

#1


7  

items, @items = @items.dup, []
@items.push(items.shift(rand(1..3))) until items.empty?

#2


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

You can limit the sub arrays size by replacing the a.size with 3 or anything you want.

您可以通过将a.size替换为3或任何您想要的内容来限制子数组的大小。

#3


1  

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.

另外,我只是想编写一个使用“rotate”方法的解决方案。

#4


1  

Just for yucks, I thought I'd try a pure functional form with no mutating methods for this problem:

只是为了yucks,我想我会尝试一个纯函数形式,没有针对这个问题的变异方法:

( (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] }

#5


0  

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]}

#1


7  

items, @items = @items.dup, []
@items.push(items.shift(rand(1..3))) until items.empty?

#2


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

You can limit the sub arrays size by replacing the a.size with 3 or anything you want.

您可以通过将a.size替换为3或任何您想要的内容来限制子数组的大小。

#3


1  

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.

另外,我只是想编写一个使用“rotate”方法的解决方案。

#4


1  

Just for yucks, I thought I'd try a pure functional form with no mutating methods for this problem:

只是为了yucks,我想我会尝试一个纯函数形式,没有针对这个问题的变异方法:

( (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] }

#5


0  

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]}