如何使用数组方法作为 Ruby 中 if 语句的条件
How to use an array method as condition for if statement in Ruby
我正在 Ruby 中构建一个井字游戏。为了确定是否有人赢得了比赛,我有一个二维数组 check_array,其中包含您可以用来获胜的所有可能集合。我想看看检查数组中的任何数组是否具有所有相同的元素。我的 javascript 大脑很难弄清楚如何在 Ruby 中做到这一点。没有我的卷发来描绘街区,我很困惑。我理解这种语法:
if check_array.any? {|row|row.uniq.count == 1}
@winner = @whos_turn
winning
end
但是如果我需要为我的 any 使用不止一行逻辑怎么办?逻辑。可以像这样吗?
if check_array.any? do |row|
row.uniq.count == 1
<<some more code>>
end
@winner = @whos_turn
winning
end
只需使用一个单独的变量。
match = check_array.any? do |row|
row.uniq.count == 1
<<some more code>>
end
if match
@winner = @whos_turn
winning
end
或者,更好的是,
def my_check(row)
row.uniq.count == 1
<<some more code>>
end
if check_array.any? { |x| my_check(x) }
@winner = @whos_turn
winning
end
我不知道建议的嵌套 do .. end
语法是否有效,但我不知道的事实表明它不是很直观,应该重构。
不管你怎么做,你当然不用担心代码的效率问题。因此,我建议您专注于可读且易于测试的代码,也许是以下几行。
game = [[:X, :O, :X],
[:O, :X, :O],
[:O, :X, :X]]
def winner(game)
return :X if player_win?(game, :X)
return :O if player_win?(game, :O)
:NO_WINNER
end
def player_win?(game, mark)
row_win?(game, mark) || col_win?(game, mark) || diag_win?(game, mark)
end
def row_win?(game, mark)
game.any? { |row| row == [mark, mark, mark] }
end
def col_win?(game, mark)
row_win?(game.transpose, mark)
end
def diag_win?(game, mark)
3.times.all? { |i| game[i][i] == mark } ||
3.times.all? { |i| game[i,2-i] == mark }
end
game = [[:X, :O, :X],
[:O, :X, :O],
[:O, :X, :X]]
winner(game)
#=> :X
game = [[:X, :O, :X],
[:O, :O, :O],
[:X, :X, :_]]
winner(game)
#=> :O
game = [[:X, :O, :X],
[:O, :O, :X],
[:X, :X, :O]]
winner(game)
#=> :NO_WINNER
我正在 Ruby 中构建一个井字游戏。为了确定是否有人赢得了比赛,我有一个二维数组 check_array,其中包含您可以用来获胜的所有可能集合。我想看看检查数组中的任何数组是否具有所有相同的元素。我的 javascript 大脑很难弄清楚如何在 Ruby 中做到这一点。没有我的卷发来描绘街区,我很困惑。我理解这种语法:
if check_array.any? {|row|row.uniq.count == 1}
@winner = @whos_turn
winning
end
但是如果我需要为我的 any 使用不止一行逻辑怎么办?逻辑。可以像这样吗?
if check_array.any? do |row|
row.uniq.count == 1
<<some more code>>
end
@winner = @whos_turn
winning
end
只需使用一个单独的变量。
match = check_array.any? do |row|
row.uniq.count == 1
<<some more code>>
end
if match
@winner = @whos_turn
winning
end
或者,更好的是,
def my_check(row)
row.uniq.count == 1
<<some more code>>
end
if check_array.any? { |x| my_check(x) }
@winner = @whos_turn
winning
end
我不知道建议的嵌套 do .. end
语法是否有效,但我不知道的事实表明它不是很直观,应该重构。
不管你怎么做,你当然不用担心代码的效率问题。因此,我建议您专注于可读且易于测试的代码,也许是以下几行。
game = [[:X, :O, :X],
[:O, :X, :O],
[:O, :X, :X]]
def winner(game)
return :X if player_win?(game, :X)
return :O if player_win?(game, :O)
:NO_WINNER
end
def player_win?(game, mark)
row_win?(game, mark) || col_win?(game, mark) || diag_win?(game, mark)
end
def row_win?(game, mark)
game.any? { |row| row == [mark, mark, mark] }
end
def col_win?(game, mark)
row_win?(game.transpose, mark)
end
def diag_win?(game, mark)
3.times.all? { |i| game[i][i] == mark } ||
3.times.all? { |i| game[i,2-i] == mark }
end
game = [[:X, :O, :X],
[:O, :X, :O],
[:O, :X, :X]]
winner(game)
#=> :X
game = [[:X, :O, :X],
[:O, :O, :O],
[:X, :X, :_]]
winner(game)
#=> :O
game = [[:X, :O, :X],
[:O, :O, :X],
[:X, :X, :O]]
winner(game)
#=> :NO_WINNER