Подтвердить что ты не робот

Как перерыв от вложенных циклов в Ruby?

предположим следующий код ruby:

bank.branches do |branch|
  branch.employees.each do |employee|
    NEXT BRANCH if employee.name = "John Doe"
  end
end

NEXT BRANCH, конечно, псевдокод. есть ли способ, которым я могу выйти из родительского цикла, как это можно сделать в Perl, например (используя метки меток)?

заблаговременно.

4b9b3361

Ответ 1

Catch и throw могут быть то, что вы ищете:

bank.branches do |branch|
  catch :missingyear do  #:missingyear acts as a label
    branch.employees.each do |employee|
      (2000..2011).each do |year|
        throw :missingyear unless something  #break out of two loops
      end
    end
  end #You end up here if :missingyear is thrown
end

Ответ 2

Нет встроенного способа выхода из блоков без их согласия. Вам просто нужно сделать что-то вроде:

bank.branches do |branch|
  break unless branch.employees.each do |employee|
    break if employee.name == "John Doe"
  end
end

Ответ 3

while c1
 while c2
    # execute code
    do_break = true if need_to_break_out_of_parent_loop
 end
 break if do_break
end

Ответ 4

Моим импульсом было бы перемещение вложенных блоков в метод с return вместо break.

def find_branch_and_employee_by_name(bank,emp_name)
  bank.branches.each do |branch|
    branch.employees.each do |employee|
      return([branch,employee]) if employee.name == emp_name
    end
  end
  nil   # employee wasn't found
end

Ответ 5

Edit: Оказывается, желаемый эффект может быть достигнут гораздо проще, вызвав перерыв внутри внутреннего цикла (только завершит этот цикл):

bank.branches do |branch|
  branch.employees.each do |employee|
    break if employee.name = "John Doe"
  end
end

Вот что писал @steenslag, написанный с помощью блока Ruby begin-rescue-end:

letters = [%w(a b c),%w(d e f),%w(g h i)]
# => [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]]

letters.each do |trine|
  begin
    trine.each do |letter|
      raise "Breaking out of inner cycle." if letter == "e"
      puts letter
    end
  rescue
    next
  end
end
# => abcdghi

Итак, ваш пример:

bank.branches do |branch|
  branch.employees.each do |employee|
    begin
      raise "Breaking out of inner cycle." if employee.name = "John Doe"
    rescue
      next
    end      
  end
end

Ответ 6

Другие сообщения ссылаются на идею, похожую на создание переменной "switch". См. Ниже для четкого примера того, как это работает. Имейте в виду, что второй цикл все равно будет работать до тех пор, пока он не достигнет конца массива employee, но не будет выполнять код после переключения переключателя. Это не оптимальный способ сделать это, так как это может быть неоправданно дорогостоящим, если массив сотрудников большой.

def workforce
  bank.branches do |branch|
    switch = 0
    branch.employees.each do |employee|
      if switch == 1
       next
      end  
      if employee.name = "John Doe"
       switch = 1
      end
   end
 end

После переключения переключателя внутренний массив больше не будет активен, и родительский цикл переместится в следующую ветвь с помощью переключателя reset. Очевидно, что для более сложных случаев можно использовать больше коммутаторов.