Ци

Цикли у Julia

2 вправи

Про концепцію Цикли

Існує фактично два типи циклів:

  1. Повторювати, доки не виконається умова.
  2. Перебирати елементи колекції.

Обидва можливі в Julia, хоча другий трапляється частіше.

Цикл while

Для задач, де кількість повторів циклу заздалегідь невідома, у Julia є цикл while.

Базова форма досить проста:

while condition
    do_something()
end

У цьому разі програма повторюватиме цикл, доки condition більше не буде true.

Є два способи достроково вийти з циклу:

  • break перериває цикл, і виконання продовжується з наступного рядка після end циклу.
  • return x зупиняє виконання поточної функції та повертає значення x тому, хто її викликав.

Коли ці можливості доступні, іноді зручно створити «нескінченний» цикл while true ... end, а потім покладатися на те, що всередині тіла циклу знайдеться умова зупинки, яка викличе break чи return.

Перебір елементів колекції

Найпростіший приклад - цикл по діапазону.

Якщо ми хочемо виконати щось 10 разів:

for n in 1:10
    do_something(n)
end

Якщо поточна ітерація не задовольняє якусь умову, можна одразу перейти до наступної ітерації за допомогою continue:

for n in 1:10
    if is_useless(n)
        continue
    end
    
    # we decided this iteration could be useful
    do_something_slow(n)
end

У коротшій формі блок if можна замінити на is_useless(n) && continue.

Можна перебирати й багато інших типів колекцій: елементи масиву, символи рядка тексту (англ. string), ключі словника...

Вимога одна: колекція має бути iterable. Докладніше про це йтиметься в одній із наступних концепцій, але по суті колекція повинна вміти видавати наступний елемент на запит і повідомляти, що досягнуто кінця й більше елементів немає.

У прикладах вище ми перебираємо діапазон 1:10, де значення є водночас індексом циклу.

Загалом може знадобитися не лише значення, а й індекс. Для цього використовують функцію eachindex(), наприклад for i in eachindex(my_array) ... end.

Включення

Явні цикли в Julia трапляються рідше, ніж у багатьох традиційних мовах, бо є чимало лаконічніших способів.

Особливо часто виникає ситуація, коли потрібно побудувати новий вектор з елементів якоїсь іншої колекції (вектора, рядка тексту, множини... можливостей багато).

Тим, хто любить спискові включення в Python, приємно буде дізнатися, що в Julia можна використовувати подібний синтаксис.

Суть у тому, що дуже компактний цикл записують усередині вектора.

Найпростіший синтаксис має вигляд result = [f(x) for x in some_collection].

Із традиційним циклом це записали б так:

result = []
for x in some_collection
    push!(result, f(x))
end

За бажанням можна додати в кінці умову, щоб вибрати лише ті елементи колекції, які відповідають умові:

# multiples of 3
julia> [n^2 for n in 1:10 if n%3 == 0]
3-element Vector{Int64}:
  9
 36
 81

# letters beyond 'h' in the alphabet
julia> [uppercase(c) for c in "Julia" if c > 'h']
3-element Vector{Char}:
 'U': ASCII/Unicode U+0055 (category Lu: Letter, uppercase)
 'L': ASCII/Unicode U+004C (category Lu: Letter, uppercase)
 'I': ASCII/Unicode U+0049 (category Lu: Letter, uppercase)

Синтаксис подібний до Python, але не ідентичний. Є деякі розбіжності для кількох змінних та/або багатовимірних масивів, тож цю тему докладніше розглянемо в одній із наступних концепцій.

Інші можливості

Як сучасна, переважно функціональна мова, Julia (звісно) має безліч способів працювати з колекціями, і не лише явний цикл чи компактний цикл у включенні.

У наступних концепціях ми розглянемо такі альтернативи, як broadcasting і функції вищого порядку.

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Цикли