Как использовать метод массива в качестве условия для оператора if в Ruby

#arrays #ruby #conditional-statements

#массивы #рубин #условные утверждения

Вопрос:

Я создаю игру в крестики — нолики в Ruby. Чтобы определить, выиграл ли кто-то в игре, у меня есть 2d-массив, check_array, из всех возможных наборов, которые вы могли бы использовать для победы. Я хочу посмотреть, есть ли в любом из этих массивов в контрольном массиве все одинаковые элементы. Моему мозгу на javascript трудно понять, как это сделать в Ruby. Я в замешательстве без своих кудряшек, чтобы очертить блок. Я понимаю такой синтаксис:

 if check_array.any? {|row|row.uniq.count == 1}  @winner = @whos_turn  winning end   

Но что, если мне нужно использовать более одной логической линии для моей любой? Логические. Могло ли это выглядеть так?

 if check_array.any? do |row|  row.uniq.count == 1  lt;lt;some more codegt;gt;  end  @winner = @whos_turn  winning end   

Комментарии:

1. lt;lt;some more codegt;gt; Вероятно, это должно быть за пределами any? «s do end «.

2. Это может быть, но это зависит от того, чего вы хотите достичь. Если переданный блок any? возвращает значение true, if то значение будет истинным. Поскольку блок может содержать столько кода (и логики), сколько вы хотите, вы можете делать внутри него все, что хотите.

Ответ №1:

Просто используйте отдельную переменную.

 match = check_array.any? do |row|  row.uniq.count == 1  lt;lt;some more codegt;gt; end if match   @winner = @whos_turn  winning end   

или, что еще лучше,

 def my_check(row)  row.uniq.count == 1  lt;lt;some more codegt;gt; end  if check_array.any? { |x| my_check(x) }  @winner = @whos_turn  winning end  

Я не знаю, работает ли предлагаемый вложенный do .. end синтаксис, но тот факт, что я понятия не имею, указывает мне на то, что он не очень интуитивно понятен и должен быть переработан.

Комментарии:

1. Или со вторым использованием check_array.any?(amp;method(:my_check)) . Или используйте лямбду вместо метода и скажите check_array.any?(amp;my_check) .

Ответ №2:

Независимо от того, как вы это делаете, вам, безусловно, не нужно беспокоиться об эффективности кода. Поэтому я предлагаю вам сосредоточиться на коде, который читаем и прост в тестировании, возможно, что-то из следующих строк.

Предполагать:

 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)  return :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 того, как определено выше,

 winner(game)  #=gt; :X  
 game = [[:X, :O, :X],  [:O, :O, :O],   [:X, :X, :_]] winner(game)  #=gt; :O  
 game = [[:X, :O, :X],  [:O, :O, :X],   [:X, :X, :O]] winner(game)  #=gt; :NO_WINNER