Ruby / Rails如何拆分数组指定步骤

时间:2013-09-14 15:02:23

标签: ruby-on-rails ruby

我们假设我有一个数组arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

如何拆分此数组以获取包含步骤?

指定元素的组

例如:

input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
...
output = [[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]]

有没有内置功能或优雅的方式来做到这一点?

3 个答案:

答案 0 :(得分:4)

使用Enumerable#each_sliceArray#zip

请尝试以下操作:

input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
n = 3
x = input.each_slice(n).to_a # => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
output = x[0].zip(*x[1..-1]).map(&:compact) # => [[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]]

很遗憾,您无法在此处使用Array#transpose

>> input.each_slice(3).to_a.transpose
IndexError: element size differs (1 should be 3)
        from (irb):15:in `transpose'
        from (irb):15
        from C:/Ruby200-x64/bin/irb:12:in `<main>'

更新:替代

input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
n = 3
output = (1..n).map { [] }
input.each_with_index do |x, i| output[i % n] << x end
output # => [[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]]

答案 1 :(得分:2)

如果值与您的示例相同,则可以将group_by与您的步骤结合使用作为模数:

> (1..10).group_by {|v| v % 3 }.values
=> [[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]] 

如果它们不是连续的,那么你仍然可以在单行中进行,虽然它不那么优雅:

> (1..10).each_with_index.group_by {|v| v[1] % 3 }.map {|k,v| v.map &:first }
=> [[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]] 

答案 2 :(得分:1)

我会这样做如下:

n = 3
input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a = input.each_slice(n).to_a
output = (0...n).map { |i| a.map{|e| e[i]}.compact }
# => [[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]]

以方法方式表示 @falsetru 的链接:

def divide(input, n)
  a = input.each_slice(n).to_a
  (0...n).map { |i| a.map{|e| e[i]}.compact }
end

p divide([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3)
p divide([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], 3)
p divide([1, 2, 3], 3)
# >> [[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]]
# >> [[1, 4, 7, 10, 13, 16], [2, 5, 8, 11, 14], [3, 6, 9, 12, 15]]
# >> [[1], [2], [3]]