我想过滤一个采用所需列索引的二维数组,并返回仅包含那些列的二维数组。除了一个空数组,我想返回相同的二维数组。
另外我不想修改原始数组,并且我想编写没有任何if语句的代码,或者尽可能地限制分支。
我想知道Marshal#load
和Marshal#dump
是否多余,并使用#map!
。
我选择使用#map!
的原因是我不必使用if..else..end
块,但我很想学习其他策略。
以下是我的解决方案:
def keep_columns args
matrix = Marshal.load Marshal.dump args[:matrix]
columns = args[:columns]
matrix.map! do |row|
row.select.with_index { |_,idx| columns.include? idx }
end unless columns.empty?
matrix
end
matrix = [['foo','bar', 'baz'],['cats', 'and', 'dogs']]
keep_columns matrix: matrix, columns: [0,2]
#=> [["foo", "baz"], ["cats", "dogs"]]
keep_columns matrix: matrix, columns: []
#=> [["foo", "bar", "baz"], ["cats", "and", "dogs"]]
答案 0 :(得分:2)
您可以在Array#transpose之前和之后使用Hash#values_at。
def extract_columns(arr, columns)
return arr if columns.empty?
arr.transpose.values_at(*columns).transpose
end
arr = [['foo','bar', 'baz'],['cats', 'and', 'dogs']]
extract_columns(arr, [0, 2])
#=> [["foo", "baz"], ["cats", "dogs"]]
extract_columns(arr, [])
#=> [["foo", "bar", "baz"], ["cats", "and", "dogs"]]
请注意,arr
未被修改。
答案 1 :(得分:1)
试试这个
matrix.map(&:dup)
这会创建矩阵的副本。
Pro tipp - 您的代码对最内层循环中的每个元素进行columns
线性搜索,可能会使用row.values_at(*columns)
代替?
def keep_columns(args)
columns, matrix = args.values_at(:columns, :matrix)
return matrix.map(&:dup) if columns.empty?
matrix.map { |row| row.values_at(*columns) }
end