【问题标题】:Splitting an array into x arrays将一个数组拆分为 x 个数组
【发布时间】:2015-07-14 09:19:29
【问题描述】:

我有一个数组:

arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

我想将arr1 分成 x 个切片,其中每个切片尽可能完整且相等。

arr2  = arr1.foo(3)
# => [1, 2, 3, 4][5, 6, 7][8, 9, 10]

each_slice 与我想要的相反,而是将数组分成 x 元素组。

arr2 = arr1.each_slice(3)
# => [1, 2, 3][4, 5, 6][7, 8, 9][10]

如果可能,我希望不使用特定于 Rails 的方法,例如 in_groups。

【问题讨论】:

标签: arrays ruby sorting


【解决方案1】:
class Array
  def in_groups(n)
    len, rem = count.divmod(n)
    (0...n).map { | i | (i < rem) ? self[(len+1) * i, len + 1] : self[len * i + rem, len] }
  end
end

【讨论】:

  • 你可以在这里使用len, rem = count.divmod(n)
  • 我会花一些时间来解析所有这些。做我需要的。
【解决方案2】:

另一种方法:

def in_groups(array, n)
  a = array.dup
  n.downto(1).map { |i| a.pop(a.size / i) }.reverse
end

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

in_groups(arr, 1) #=> [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
in_groups(arr, 2) #=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
in_groups(arr, 3) #=> [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
in_groups(arr, 4) #=> [[1, 2, 3], [4, 5, 6], [7, 8], [9, 10]]
in_groups(arr, 5) #=> [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]

【讨论】:

  • 现在这令人惊讶。
【解决方案3】:

你可以使用递归:

def in_groups(arr, n)
  return [arr] if n == 1
  len = arr.size/n
  [arr[0,len]].concat in_groups(arr[len..-1], n-1)
end

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

in_groups(arr,  1) #=> [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]] 
in_groups(arr,  2) #=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]] 
in_groups(arr,  3) #=> [[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]] 
in_groups(arr,  4) #=> [[1, 2], [3, 4], [5, 6, 7], [8, 9, 10]] 
in_groups(arr,  5) #=> [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] 
in_groups(arr,  9) #=> [[1], [2], [3], [4], [5], [6], [7], [8], [9, 10]] 
in_groups(arr, 10) #=> [[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]] 
in_groups(arr, 11) #=> [[], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10]] 

编辑 1:对于最大的群体,首先添加 .reverse 或将倒数第二行替换为:

len = (arr.size.to_f/n).ceil

编辑 2:以下是 @undur 答案的一个轻微变体,对于大脑类型为“B”和“C”的人来说可能更容易理解:

class Array
  def in_groups(n)
    size_small, nbr_large = count.divmod(n)
    size_large, nbr_small = size_small+1, n-nbr_large
    nbr_for_large = nbr_large * size_large  
    self[0, nbr_for_large].each_slice(size_large).to_a.concat(
      self[nbr_for_large..-1].each_slice(size_small).to_a)
  end
end

(1..10).to_a.in_groups(3)
  #=> [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] 

【讨论】:

  • 很好地使用了递归。但我认为 OP 希望切片从左到右填充,即[[1,2,3,4], [5,6,7], [8,9,10]]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 2012-05-28
  • 2013-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多