Эквивалент Applescript для продолжения?

У меня есть простое «повторение с» в AppleScript, и я хотел бы перейти к следующему элементу в «повторении» условно. В основном я ищу что-то похожее на «продолжить» (или прервать?) на других языках.

Я не очень хорошо разбираюсь в AppleScript, но уже несколько раз находил его полезным.


person danieljimenez    schedule 21.06.2009    source источник


Ответы (7)


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

Applescript имеет exit repeat, который полностью завершает цикл, пропуская все оставшиеся итерации. Это может быть полезно в бесконечном цикле, но в данном случае это не то, что нам нужно.

По-видимому, в AppleScript не существует функции, подобной continue, но вот трюк для ее имитации:

set aList to {"1", "2", "3", "4", "5"}

repeat with anItem in aList -- # actual loop
    repeat 1 times -- # fake loop
        set value to item 1 of anItem

        if value = "3" then exit repeat -- # simulated `continue`

        display dialog value
    end repeat
end repeat

Это отобразит диалоги для 1, 2, 4 и 5.

Здесь вы создали два цикла: внешний цикл — это ваш реальный цикл, внутренний цикл — это цикл, который повторяется только один раз. exit repeat выйдет из внутреннего цикла, продолжая внешний цикл: именно то, что мы хотим!

Очевидно, что если вы воспользуетесь этим, вы потеряете способность делать обычные exit repeat.

person Tom Lokhorst    schedule 23.06.2009
comment
Приведенный выше код не скомпилируется, потому что комментарии в applescript -- не # - person alexyorke; 07.12.2009
comment
В applescript 2.0 для комментариев также разрешен знак #: developer.apple.com/library/mac/documentation/applescript/ - person Joakim; 20.09.2012
comment
Код все равно скомпилируется, потому что «--» предшествует всем «#», а «--» всегда отмечает комментарий в AppleScript. - person Simon White; 24.01.2016

set aList to {"1", "2", "3", "4", "5"}

repeat with anItem in aList -- # actual loop
    try
        set value to item 1 of anItem

        if value = "3" then error 0 -- # simulated `continue`

        log value
    end try
end repeat

Это по-прежнему даст вам возможность «повторить выход».

person Skeeve    schedule 07.11.2010

set aList to {"1", "2", "3", "4", "5"}

repeat with anItem in aList -- # actual loop
    try -- # needed to simulate continue
        set value to item 1 of anItem
        if value = "3" then continueRepeat -- # simulated `continue` throws an error to exit the try block

        log value
    on error e
        if e does not contain "continueRepeat" then error e -- # Keeps error throwing intact
    end try
end repeat

На основе описанного выше подхода на основе блока try, но читается немного лучше. Конечно, поскольку continueRepeat не определен, будет выдана ошибка, из-за которой остальная часть блока try будет пропущена.

Чтобы сохранить выдачу ошибок без изменений, включите предложение on error, которое выдает любую непредвиденную ошибку.

person Daniel Schlaug    schedule 15.05.2011

-- Или вы можете использовать другую стратегию: использовать цикл для цикла и выполнять условную логику в обработчике, например:

set aList to {"1", "2", "3", "4", "5"}

repeat with anItem in aList
   doConditionalWork(anItem as string)
end repeat

on doConditionalWork(value)

   if value = "3" then return

   display dialog value

end doConditionalWork
person Ron Reuter    schedule 20.02.2013

Вы все все усложняете. Попробуй это:

set aList to {"1", "2", "3", "4", "5"}

repeat with anItem in aList
    set value to item 1 of anItem
    if value is not "3" then log value
end repeat
person Eurobubba    schedule 22.02.2013

Вы также можете использовать «repeat while» для циклов, которые повторяются только условно.

person Simon White    schedule 24.01.2016

Основываясь на ответе Тома Лохорста, вот вариант выполнения break или continue в зависимости от установленной вами переменной isExit . Для этого в конце внешнего (не поддельного) цикла вы добавляете

if isExit then
    exit repeat
end if

Таким образом, если isExit истинно, вы просто выходите из внешнего цикла, являясь эффективным break.

Оригинальный вопрос/ответ:

Для исходной проблемы с вопросом это будет выглядеть так, ниже будет обобщенная.

set aList to {"1", "2", "3", "4", "5"}

repeat with anItem in aList -- actual loop
    set isExit to false
    repeat 1 times -- fake loop
        -- do your stuff
        set value to item 1 of anItem

        if value = "3" then 
            -- simulated `continue`
            set isExit to false
            exit repeat
        end if

        if value = "69" then 
        -- simulated `break`
            set isExit to true
            exit repeat
        end if
        
        display dialog value
    end repeat

    if isExit then
        exit repeat
    end if
end repeat

Обобщенный

Итак, чтобы разбить это на более простой пример:

Допустим, вы хотели бы иметь continue или break в этих двух if. Вы можете поместить весь свой код между ними, я включил только код, относящийся к различным стратегиям выхода.

Если вы хотите написать что-то вроде этого:

repeat <condition_repeat>
    if <condition_continue> then
        continue
    end if
    if <condition_break> then
        break
    end if
end repeat

Это можно было бы записать как

repeat <condition_repeat>
    set isExit to false                -- added 
    repeat 1 times                     -- added 
        if <condition_continue> then
            set isExit to false        -- changed
            exit repeat                -- changed
        end if
        if <condition_break> then
            set isExit to true         -- changed
            exit repeat                -- changed
        end if
    end repeat                         -- added
    if isExit then                     -- added
        exit repeat                    -- added
    end if                             -- added
end repeat
person luckydonald    schedule 16.02.2021