将行转为列(对我可以使用的方法有限制)
Transposing rows to columns (with limitations on what methods I can use)
我正在做一道练习题,问题是将 Ruby 中的行转置为列。
我理解 while
循环是 Ruby 中的 "rookie-esque",但我认为他们更喜欢我使用基本方法和控制流程语句:while
、each
, map
.显然,我不能使用Array#transpose
。他们想让我基本上从头开始写 Array#transpose
。
它一直告诉我:
undefined method `[]=' for nil:NilClass (NoMethodError)
这是我的代码:
def transpose(rows)
idx1 = 0
cols = []
while idx1 < rows.count
idx2 = 0
while idx2 < rows[idx1].count
cols[idx1][idx2] = rows[idx2][idx1]
idx2 += 1
end
idx1 += 1
end
return cols
end
puts transpose(rows = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
])
在你的外部 while
循环中,你需要使 cols[idx1]
成为一个空数组,否则在你的内部 while
循环中它是 nil
:
while idx1 < rows.count
cols[idx1] = []
idx2 = 0
while idx2 < rows[idx1].count
# ...
end
end
也许这会对你有所帮助:
def transpose(rows)
idx1 = 0 # => 0
cols = [] # => []
while idx1 < rows.count # => true
idx2 = 0 # => 0
while idx2 < rows[idx1].count # => true
cols[idx1][idx2] = rows[idx2][idx1] # ~> NoMethodError: undefined method `[]=' for nil:NilClass
idx2 += 1
end
idx1 += 1
end
return cols
end
puts transpose(rows = [
[0, 1, 2], # => [0, 1, 2]
[3, 4, 5], # => [3, 4, 5]
[6, 7, 8] # => [6, 7, 8]
])
# ~> NoMethodError
# ~> undefined method `[]=' for nil:NilClass
这是使用 "Seeing Is Believing" 在 Sublime Text 2 中创建的。
分解一下,这是你出错的地方:
cols = [] # => []
cols[0] # => nil
cols[0][0] # ~> NoMethodError: undefined method `[]' for nil:NilClass
您不能在 nil 上使用子索引。空数组中不存在第一个索引。
你可以使用 Array#new 和块来做到这一点:
Array.new(rows.size) { |i| Array.new(rows.size) { |j| rows[j][i] } }
#=> [[0, 3, 6], [1, 4, 7], [2, 5, 8]]
或者,您可以使用 class Matrix 中的方法,您需要:
require 'matrix'
这里有一个不使用Array#transpose的简单方法,虽然它可能不符合问题的精神:
Matrix[*rows].transpose.to_a
#=> [[0, 3, 6], [1, 4, 7], [2, 5, 8]]
但是,您可以这样做:
Matrix.build(rows.size) { |i,j| rows[j][i] }.to_a
#=> [[0, 3, 6], [1, 4, 7], [2, 5, 8]]
使用嵌套 Enumerable#map
s 进行比较的另一种方法:
rows = [[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]
def my_transpose(matrix)
matrix.first.size.times.map { |column| matrix.map { |row| row[column] } }
end
my_transpose(rows)
# => [[0, 3, 6], [1, 4, 7], [2, 5, 8]]
my_transpose(my_transpose(rows))
# => [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
我正在做一道练习题,问题是将 Ruby 中的行转置为列。
我理解 while
循环是 Ruby 中的 "rookie-esque",但我认为他们更喜欢我使用基本方法和控制流程语句:while
、each
, map
.显然,我不能使用Array#transpose
。他们想让我基本上从头开始写 Array#transpose
。
它一直告诉我:
undefined method `[]=' for nil:NilClass (NoMethodError)
这是我的代码:
def transpose(rows)
idx1 = 0
cols = []
while idx1 < rows.count
idx2 = 0
while idx2 < rows[idx1].count
cols[idx1][idx2] = rows[idx2][idx1]
idx2 += 1
end
idx1 += 1
end
return cols
end
puts transpose(rows = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
])
在你的外部 while
循环中,你需要使 cols[idx1]
成为一个空数组,否则在你的内部 while
循环中它是 nil
:
while idx1 < rows.count
cols[idx1] = []
idx2 = 0
while idx2 < rows[idx1].count
# ...
end
end
也许这会对你有所帮助:
def transpose(rows)
idx1 = 0 # => 0
cols = [] # => []
while idx1 < rows.count # => true
idx2 = 0 # => 0
while idx2 < rows[idx1].count # => true
cols[idx1][idx2] = rows[idx2][idx1] # ~> NoMethodError: undefined method `[]=' for nil:NilClass
idx2 += 1
end
idx1 += 1
end
return cols
end
puts transpose(rows = [
[0, 1, 2], # => [0, 1, 2]
[3, 4, 5], # => [3, 4, 5]
[6, 7, 8] # => [6, 7, 8]
])
# ~> NoMethodError
# ~> undefined method `[]=' for nil:NilClass
这是使用 "Seeing Is Believing" 在 Sublime Text 2 中创建的。
分解一下,这是你出错的地方:
cols = [] # => []
cols[0] # => nil
cols[0][0] # ~> NoMethodError: undefined method `[]' for nil:NilClass
您不能在 nil 上使用子索引。空数组中不存在第一个索引。
你可以使用 Array#new 和块来做到这一点:
Array.new(rows.size) { |i| Array.new(rows.size) { |j| rows[j][i] } }
#=> [[0, 3, 6], [1, 4, 7], [2, 5, 8]]
或者,您可以使用 class Matrix 中的方法,您需要:
require 'matrix'
这里有一个不使用Array#transpose的简单方法,虽然它可能不符合问题的精神:
Matrix[*rows].transpose.to_a
#=> [[0, 3, 6], [1, 4, 7], [2, 5, 8]]
但是,您可以这样做:
Matrix.build(rows.size) { |i,j| rows[j][i] }.to_a
#=> [[0, 3, 6], [1, 4, 7], [2, 5, 8]]
使用嵌套 Enumerable#map
s 进行比较的另一种方法:
rows = [[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]
def my_transpose(matrix)
matrix.first.size.times.map { |column| matrix.map { |row| row[column] } }
end
my_transpose(rows)
# => [[0, 3, 6], [1, 4, 7], [2, 5, 8]]
my_transpose(my_transpose(rows))
# => [[0, 1, 2], [3, 4, 5], [6, 7, 8]]