我有一個關於識別矩陣中某個給定單元格或某組單元格旁邊所有點的問題(請參閱Need a Ruby way to determine the elements of a matrix "touching" another element)。由於沒有提出合適的想法,我決定通過強力行動。何時以及如何將代碼段轉換爲紅寶石方法
下面的代碼成功地做了我想要做的事情。數組tmpl(模板)包含如何從給定座標(由atlantis提供)到周圍8個單元的映射。然後,我通過將atlantis的每個元素與tmpl的所有元素相加來構建一個包含所有「atlantis」海岸線的「水下」土地的陣列sl(海岸線)。
# create method to determine elements contiguous to atlantis
require 'matrix'
atlantis = [[2,3],[3,4]]
tmpl = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]]
ln = 0
sl = []
while ln < atlantis.length
n = 0
tsl = []
while n < 8
tsl[n] = [atlantis[ln], tmpl[n]].transpose.map { |x| x.reduce(:+) }
n = n+ 1
end
sl = sl + tsl
ln = ln + 1
end
sl = sl - atlantis
sl.uniq!
sl.to_a.each { |r| puts r.inspect }
但是我有一個問題,我仍然需要2級以上此處顯示的循環(許多剩餘的一個)(一個繼續增加土地亞特蘭蒂斯,直到它達到設定規模和另一作出更多島嶼,百慕大羣島,卡塔利娜島等),而且這已經變得難以閱讀和遵循。對面向對象編程的模糊理解表明,通過將這些循環轉化爲方法可以改進這種冷感。然而,我學會了35年前的基礎課程,並努力學習Ruby。所以我的要求是:
事實上,更好地把它們變成方法?
如果是這樣,任何人都願意告訴我如何通過改變某種方法來做到這一點?
當您添加更多關卡並發現您需要在較低方法中更改某些內容時,您會做什麼? (例如,搞清楚如何在
atlantis
只是一個價值創造sl
的簡單情況後,我不得不回去返工更長的值。)
我問這個問題希望通過這種方式,它變得對其他nubies有用。
順便說一下,這個位.transpose.map { |x| x.reduce(:+) }
我在Stack Overflow上找到了(經過幾小時的努力,因爲它應該很簡單,如果我做不到,我一定會漏掉一些明顯的東西。 )使您可以通過添加元素的兩個數組元素,我不知道它是如何工作的。)
也許專注於理解你先寫的東西。我還會考慮使用更多的空白,以便代碼更易於閱讀。 – 2012-07-29 23:54:49
讓你的代碼更像'ruby-like'的一種方法是將你在這裏的兩個循環替換爲更有意義的東西。兩者都可以替換爲'each'方法(參見http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-each),這將使它更容易理解什麼你的代碼試圖去做。 – 2012-07-30 01:18:02
當你希望不止一次地做同樣的操作時,你只需要制定一個方法。如果這個腳本只能有效地調用這個「方法」一次,那麼不需要真的改變它。你甚至可以爭辯說,這樣做會[不成熟的優化](http://c2.com/cgi/wiki?PrematureOptimization)。 – lyonsinbeta 2012-07-30 03:05:40