Ruby:重构复杂的嵌套循环方法
我试图消除代码中的重复。我有一种用棋盘填充棋盘的方法:Ruby:重构复杂的嵌套循环方法,ruby,refactoring,iteration,Ruby,Refactoring,Iteration,我试图消除代码中的重复。我有一种用棋盘填充棋盘的方法: def populate_checkers evens = [0, 2, 4, 6] odds = [1, 3, 5, 7] 0.upto(2) do |x_coord| if x_coord.even? evens.each do |y_coord| red_checker = Checker.new(x_coord, y_coord, :red) @board[x_co
def populate_checkers
evens = [0, 2, 4, 6]
odds = [1, 3, 5, 7]
0.upto(2) do |x_coord|
if x_coord.even?
evens.each do |y_coord|
red_checker = Checker.new(x_coord, y_coord, :red)
@board[x_coord][y_coord] = red_checker
end
elsif x_coord.odd?
odds.each do |y_coord|
red_checker = Checker.new(x_coord, y_coord, :red)
@board[x_coord][y_coord] = red_checker
end
end
end
5.upto(7) do |x_coord|
if x_coord.even?
evens.each do |y_coord|
black_checker = Checker.new(x_coord, y_coord, :black)
@board[x_coord][y_coord] = black_checker
end
elsif x_coord.odd?
odds.each do |y_coord|
black_checker = Checker.new(x_coord, y_coord, :black)
@board[x_coord][y_coord] = black_checker
end
end
end
end
我怎样才能消除重复并仍然获得所需的精确行为
def populate_checkers
evens = [0, 2, 4, 6]
odds = [1, 3, 5, 7]
[0.upto(2), 5.upto(7)].each_with_index do |enum, i|
enum.each do |x_coord|
(x_coord.even? ? evens : odds).each do |y_coord|
checker = Checker.new(x_coord, y_coord, i == 0 ? :red : :black)
@board[x_coord][y_coord] = checker
end
end
end
end
也许有更好的方法来计算,但这就是我得到的
这里有一个可能更好的解决方案
def populate_checkers
{ :red => (0..2), :black => (5..7) }.each do |color, range|
range.each do |x_coord|
(x_coord.even? ? 0 : 1).step(7, 2) do |y_coord|
checker = Checker.new(x_coord, y_coord, color)
@board[x_coord][y_coord] = checker
end
end
end
end
您可以尝试提取一个方法,然后将一个块提取到lambda中。那么你的代码将是可读的,没有重复
def populate_checkers
0.upto(2) do |x_coord|
populate_checker(x_coord, :red)
end
5.upto(7) do |x_coord|
populate_checker(x_cord, :black)
end
end
def populate_checker(x_coord, color)
evens = [0, 2, 4, 6]
odds = [1, 3, 5, 7]
apply_checker = lambda do |y_coord|
checker = Checker.new(x_coord, y_coord, color)
@board[x_coord][y_coord] = checker
end
if x_coord.even?
evens.each(&apply_checker)
elsif x_coord.odd?
odds.each(&apply_checker)
end
end
这只适用于红军。旁注:从函数式编程的角度来看,这种代码非常糟糕。你调用了一个方法,“神奇地”某个实例变量(@board)被填充了,唉,引用透明度下降了。更好地编写获取参数并返回内容的方法:
@board=build\u board
。有关FP with Ruby的更多信息:
0.upto(2) do |x|
0.upto(7) do |y|
@board[x][y]=Checker.new(x, y, :red) if (x+y).even?
end
end