There are basically two types of loops:
Both are possible in Julia, though the second may be more common.
while
loopFor open-ended problems where the number of times round the loop is unknown in advance, Julia has the while
loop.
The basic form is fairly simple:
while condition
do_something()
end
In this case, the program will keep going round the loop until condition
is no longer true
.
Two ways to exit the loop early are available:
break
causes the loop to exit, with execution continuing at the next line after the loop end
.return x
stops execution of the current function, passing the return value x
back to the caller.With these options available, it can sometimes be convenient to create an "infinite" loop with while true ... end
, then rely on finding a stopping condition within the loop body to trigger a break
or return
.
The simplest illustration is to loop over a range.
If we want to do something 10 times:
for n in 1:10
do_something(n)
end
If the current iteration fails to satisfy some condition, it is possible to skip immediately to the next iteration with a continue
:
for n in 1:10
if is_useless(n)
continue
end
# we decided this iteration could be useful
do_something_slow(n)
end
In a shorter form, the if
block could be replaced by is_useless(n) && continue
.
Many other collection types can be looped over: elements in an array, characters in a string, keys in a dictionary...
The requirement is that the collection must be iterable
.
This will be explained in more detail in a later Concept, but in essence the collection must have a way to yield the next item when asked, plus a way to indicate the end is reached and there are no more items.
The examples so far loop over the range 1:10
, where the value is also the loop index.
More generally, the index may be needed and not just the value.
For this, the eachindex()
function is used, for example for i in eachindex(my_array) ... end
.
Writing explicit loops tends to be less common in Julia than in many traditional languages, because there are various more concise options.
A particularly common situation is when we need to build a new vector from the elements of some other collection (vector, string, set ... there are many possibilities).
Anyone who likes list comprehensions in Python will be pleased to know that Julia can use similar syntax.
The essence of this is to set up a very compact loop inside a vector.
The simplest syntax is of the form result = [f(x) for x in some_collection]
.
With a traditional loop, that might be written:
result = []
for x in some_collection
push!(result, f(x))
end
Optionally, a conditional can be added at the end, to select only matching elements in the collection:
# 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)
The syntax is similar to Python, but not identical. There is some divergence for multiple variables and/or multi-dimensional arrays, so this topic will be covered in more detail in a later Concept.
As a modern, mostly-functional language, Julia (of course) has a variety of ways to operate on collections, not just an explicit loop, or a compacted loop in a comprehension.
Later concepts will look at alternatives such as broadcasting and higher-order functions.