2012-08-12 65 views
1

我具有指示的座標值,像這樣數組的數組:紅寶石:結合數組值

cells = [ [0,0], [0,1] ] 

陣列中的每個陣列是X和Y值。所以,如果我想改變這個權利,那麼在每個單元格上將會是X+1。我可以表達這種像這樣的小區:

delta = [1,0] 

現在,我想要做的是合併該值到每個細胞,使每個單元的X值與增量值相加,所以在這種情況下,最終的輸出應該是:

new_cells = [ [1,0], [1,1] ] 

下面是我能想到的迄今爲止最好的,看來真的是沉重的:

cells = [[0,0],[0,1]] 
delta = [1,0] 
cells.each do |cell| 
    cell[0] = cell[0] + delta[0] 
    cell[1] = cell[1] + delta[1] 
end 
# Now cells = [[1,0],[1,1]] 

是否有一個更清潔的一行樣的方法,將總和一個ARR ay到數組鏈中的每個數組上,還是上述問題的最佳解決方案?

+0

需要它是就地更新?你這樣做會失去一些美好的東西...... – tokland 2012-08-13 08:05:34

回答

3

我覺得你最好的解決辦法是要認識到細胞和三角洲是如果它不是一個數組,你可以更清楚的操作在不同的數據類型:

Cell = Struct.new(:x, :y) do 
    def + other 
    Cell.new(self.x + other.x, self.y + other.y) 
    end 
end 

# cells is some array of Cell objects 
# delta is some Cell object 

cells.map! {|cell| cell + delta} 
+1

這是一個有趣的事情。我認爲它可能是最乾淨的實現,並且從Struct構建允許一個非常簡潔的定義。感謝所有的投入,我喜歡這個最好的! – Andrew 2012-08-13 03:13:51

2

這裏:

cells = cells.map {|c| [c[0] + delta[0], c[1] + delta[1]] } 
1
cells.map! {|x, y| [x + delta[0], y + delta[1]] } 

注意Linuxios的答案,我的答案,你的解決方案都有不同的效果,如果別人已經包含在對細胞陣列或細胞的一個參考陣列。只有您的答案會修改原始單元格,因此使用我的解決方案或Linuxios的解決方案引用可能仍然指向舊數據。

+0

在這個答案中,如果你使用#map!不會修改單元格嗎?假設沒有任何組成單元格作爲變量存儲在其他地方,一旦「單元格」被爆炸映射,我不確定我會看到舊值如何仍然存在...... – Andrew 2012-08-12 23:10:41

+0

@Andrew:如果其中一個單元格在別處被引用,我的解決方案不會更新該參考,但您的將會。如果在其他地方引用'cells'數組,Linuxios的解決方案將不會更新該引用,但您的解決方案和我的解決方案將會。 – 2012-08-13 01:44:47

1
cells.map {|cell| cell.zip(delta).map{|x, y| x + y }} 

我不認爲這比其他解決方案更清潔。

+0

+1。這就是我寫的東西,它可以工作,不管矢量大小。 – tokland 2012-08-12 22:50:46

+0

我對#zip並不熟悉。我看到[docs](http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-zip),但對我來說還是有點不清楚。你介意在這種情況下詳細闡述一下#zip在做什麼? – Andrew 2012-08-12 23:08:26

+0

@Andrew:'[1,2,3] .zip([4,5,6])'給出結果'[[1,4],[2,5],[3,6]]'。 – 2012-08-13 01:45:22

1

這裏是你怎麼不擔心匹配與三角洲的細胞鍵:

cells = cells.map {|cell| [cell,delta].transpose.map {|value| value.reduce(:+)}} 

一步一步:

cells = cells.map { |cell|   # => [0,0] 

    combined = [cell, delta]   # => [[0,0], [1,0]] 

    transposed = combined.transpose # => [[0, 1], [0, 0]] 

    new_c = transposed.map { |value| # => [0, 1] 

    value.reduce(:+)    # => 1, => 0 

    } 

    new_c       # => [1,0] As expected for first cell. 
} 

cells        # => [[1,0],[1,1]] Final result 

與另一個樣本數據:

cells = [[0,0],[1,1],[2,2]] 
delta = [1,1] 
plug = Proc.new { 
    cells = cells.map { |cell| [cell, delta].transpose.map { |value| value.reduce(:+) } } 
} 

plug.call # => [[1, 1], [2, 2], [3, 3]] 
plug.call # => [[2, 2], [3, 3], [4, 4]] 
plug.call # => [[3, 3], [4, 4], [5, 5]] 
plug.call # => [[4, 4], [5, 5], [6, 6]] 
plug.call # => [[5, 5], [6, 6], [7, 7]] 

另一種:

cells = [[0,0,0],[0,1,2],[1,2,3],[2,3,4]] 
delta = [3,2,1] 

plug.call # => [[3, 2, 1], [3, 3, 3], [4, 4, 4], [5, 5, 5]] 
plug.call # => [[6, 4, 2], [6, 5, 4], [7, 6, 5], [8, 7, 6]] 
plug.call # => [[9, 6, 3], [9, 7, 5], [10, 8, 6], [11, 9, 7]] 
plug.call # => [[12, 8, 4], [12, 9, 6], [13, 10, 7], [14, 11, 8]] 
plug.call # => [[15, 10, 5], [15, 11, 7], [16, 12, 8], [17, 13, 9]] 

希望這能更好地回答你的問題。

+1

1)我會寫'[cell,delta] .transpose' - >'cell.zip(delta)'。 2)我認爲減少是沒有必要的,當你壓縮三角形的向量時,你總是有2個值,所以不需要減少,只需要一對。這就是肯布盧姆的答案。 – tokland 2012-08-12 22:50:02

+1

非常有趣的方法,感謝徹底的一步一步! – Andrew 2012-08-12 23:04:55

+0

@tokland:同意 – 2012-08-13 18:08:07