我正在尝试学习Ruby方式的数组处理。编写以下函数的简洁方法是什么?
def columnize(items, n_cols)
Items是一个任意长度的1D数组。我想返回一个行数组,每个行的长度为n_cols
,其中包括所有items
列,可能在最后一列填充nil
。例如:
items = [1, 2, 3, 4, 5, 6, 7]
table = columnize items, 3
这应该产生table
:
[[1, 4, 7],
[2, 5, nil],
[3, 6, nil]]
请注意,最后一列可能都是nil
,如:
columnize [1, 2, 3, 4, 5, 6, 7, 8, 9], 4
这是我需要为报告生成解决的一个真正问题。我有一个不太令人满意的Ruby新手解决方案,如果需要可以发布它。
答案 0 :(得分:4)
您想使用Matrix
课程。
items = [1, 2, 3, 4, 5, 6, 7]
require 'matrix'
# ⇒ true
m = Matrix.build(3) { |row, col| items[row+col*3] }
# ⇒ Matrix[[1, 4, 7], [2, 5, nil], [3, 6, nil]]
答案 1 :(得分:4)
Ruby的Array类有transpose
,用于将行转换为列。将其与fill
和Enumerable的each_slice
结合使用可以得到:
require 'pp'
def columnize(items, cols)
ary = items.dup.fill(nil, items.size, cols - items.size % cols )
ary.each_slice(ary.size / cols).to_a.transpose
end
items = [1, 2, 3, 4, 5, 6, 7]
pp columnize(items, 3)
pp columnize [1, 2, 3, 4, 5, 6, 7, 8, 9], 4
哪个输出:
[[1, 4, 7], [2, 5, nil], [3, 6, nil]]
[[1, 4, 7, nil], [2, 5, 8, nil], [3, 6, 9, nil]]
答案 2 :(得分:2)
除了填充只有nil
个元素的行外,这样做:
first, *rest = items.each_slice((items.length/n_cols).ceil).to_a
first.zip(*rest)