我有一个关于识别矩阵中某个给定单元格或某组单元格旁边所有点的问题(请参阅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