【问题标题】:Whats the best way to split an array in ruby into multiple smaller arrays of random size将ruby中的数组拆分为多个随机大小的较小数组的最佳方法是什么
【发布时间】:2013-03-08 22:20:59
【问题描述】:

我在 ruby​​ 中有多个长度从 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 的数组大小......实现这一目标的最佳方法是什么?

【问题讨论】:

    标签: ruby arrays random slice


    【解决方案1】:
    items, @items = @items.dup, []
    @items.push(items.shift(rand(1..3))) until items.empty?
    

    【讨论】:

    • 不错。如果一个人的 ruby​​ 早于 1.9.3 Kernel#rand 只需要一个最大的fixnum,而不是一个范围。 @items.push(items.shift(1+rand(3))) until items.empty? 适用于较旧的红宝石。
    【解决方案2】:
    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 或您想要的任何内容来限制子数组的大小。

    【讨论】:

      【解决方案3】:

      这个解决方案可能使用了太多的局部变量,但它对输入数组没有破坏性,并且可以灵活地设置数组窗口最大值。

      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..@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]+
            (1..a.length-1)
              .to_a
              .sample(rand(a.length))
              .sort+
            [a.length]
          ).each_cons(2).map{|i,j| a[i..j-1]}
          

          【讨论】:

          • 这可以产生长度 > 3 的子数组。a[i...j] 是一个更好的说法 a[i..j-1]。我相信它可能偏向于较短的子数组。
          猜你喜欢
          • 2011-08-06
          • 2012-04-06
          • 1970-01-01
          • 2018-01-22
          • 1970-01-01
          • 2010-12-09
          • 1970-01-01
          • 2010-09-16
          • 2021-03-28
          相关资源
          最近更新 更多