2015-03-08 64 views
-1

我在做一个练习题,问题是将行转换为Ruby中的列。移动行到列(限制我可以使用什么方法)

我明白while循环是“菜鸟式的”在Ruby中,但我认为他们喜欢我使用的基本方法和控制流语句:whileeachmap。很显然,我不能使用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] 
]) 
+0

什么是你的问题? – sawa 2015-03-09 02:25:04

回答

0

在你的外while循环您需要cols[idx1]一个空数组,否则它是在你的内心whilenil loop:

while idx1 < rows.count 
    cols[idx1] = [] 
    idx2 = 0 
    while idx2 < rows[idx1].count 
    # ... 
    end 
end 
+0

非常感谢,工作。你会推荐一个更好的方法来做到这一点,使用相同的方法?或者你认为我这样做的方式很好? – roonie 2015-03-08 18:39:04

1

也许这将帮助你:

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 

这是用“眼见为实”,在崇高的文本2

其分解产生,这里是你要去哪里错了:

cols = [] # => [] 
cols[0]  # => nil 
cols[0][0] # ~> NoMethodError: undefined method `[]' for nil:NilClass 

你无法在零上使用子索引。第一个索引不存在于空数组中。

0

你可能用Array#new与块:

Array.new(rows.size) { |i| Array.new(rows.size) { |j| rows[j][i] } } 
    #=> [[0, 3, 6], [1, 4, 7], [2, 5, 8]] 

或者,你可以使用的方法从类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]] 
0

另一种方式来使用嵌套Enumerable#map小号比较要这样做:

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]]