2013-10-03 40 views
2

數組元素我有兩個陣列:替換地圖

@a = [ 
    [1, 2, 3], 
    [4, 5, 6], 
    [7, 8, 9] 
] 
@b = [a, b, c] 

我需要在ab像更換第n列:

swap_column(0) 
#=> [a, 2, 3] 
    [b, 5, 6] 
    [c, 8, 9] 

(這是使用Cramer's rule用於求解方程系統,如果有人想知道)

我想出的代碼是:

def swap_column(n) 
    @a.map.with_index { |row, j| row[n] = @b[j] } 
    end 

我該如何擺脫這裏的任務,以便map返回修改的矩陣,同時使@a保持不變?

回答

2

你想要什麼是dup。另外,您的map.with_index塊的返回值錯誤。

def swap_column(i) 
    @a.map.with_index{|row, j| row = row.dup; row[i] = @b[j]; row} 
end 

def swap_column(i) 
    @a.map.with_index{|row, j| row.dup.tap{|row| row[i] = @b[j]}} 
end 
0

您可以使用transpose做到以下幾點:

class M 
    attr :a, :b 

    def initialize 
    @a = [[1,2,3], 
      [4,5,6], 
      [7,8,9] 
     ] 
    @b = [:a, :b, :c] 
    end 

    def swap_column(n) 
    t = @a.transpose 
    t[0] = @b 
    t.transpose 
    end 

end 

m = M.new 
=> #<M:0x007ffdc2952e38 @a=[[1, 2, 3], [4, 5, 6], [7, 8, 9]], @b=[:a, :b, :c]> 
m.swap_column(0) 
=> [[:a, 2, 3], [:b, 5, 6], [:c, 8, 9]] 
m # m is unchanged 
=> #<M:0x007ffdc2952e38 @a=[[1, 2, 3], [4, 5, 6], [7, 8, 9]], @b=[:a, :b, :c]> 
+2

「轉置」不是一個過度殺傷力?其中兩個,其實。我聽說在大型陣列上它可能會很慢。 –

1

由澤答案是好的,主要的一點是,你需要dup你內心的陣列,使其正常工作。這篇補充文章的唯一理由是指出,通常當您使用with_index時,您可以直接將1:1索引導入另一個數組中,您可以使用zip簡化代碼。

def swap_column(n) 
    @a.zip(@b).map {|r,e| r.dup.tap{|r| r[n] = e}} 
end 

zip做你是什麼兩個陣列結合到一個新的數組,其中每個元件是由初始陣列的兩個對應的元件的陣列。在這種情況下,它將是一個數組和一個元素的數組,以便以後用於替換。然後,我們映射這些結果並自動將每個元素解構爲兩部分。然後我們dup這個數組片和tap它來代替第n個元素。