2015-03-08 62 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]] 
相關問題