Loops
Loops¶
In Julia
there are two types of loops, for
and while
.
As of Julia 1.5
(here you can find a longer discussion on the implemented changes), the behavior of those loops are very similar to loops known in other programming languages.
for
loops repeat a finite number evaluations, which is equal to the number of elements of the provided iterable object.
Ranges and arrays are examples of iterable objects.
One very simple for
loop:
for i in [1 2 3 4]
println("i=$i")
end
i=1
i=2
i=3
i=4
The loop iterates over elements of the array [1 2 3 4]
. For each iteration the value of the iterator i
is changed to the subsequent element of the iterable object.
if you use two-dimensional arrays, the order of elements is chosen columnwisely.
A = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
for i in A
println("i=$i")
end
i=1
i=3
i=2
i=4
Loops can be nested:
for x ∈ 1:3
for y ∈ 1:2
println("x^y=$(x^y), for x=$x and y=$y.")
end
end
x^y=1, for x=1 and y=1.
x^y=1, for x=1 and y=2.
x^y=2, for x=2 and y=1.
x^y=4, for x=2 and y=2.
x^y=3, for x=3 and y=1.
x^y=9, for x=3 and y=2.
The same thing can be written in a more compact way:
for x ∈ 1:3, y ∈ 1:2
println("x^y=$(x^y), for x=$x and y=$y.")
end
x^y=1, for x=1 and y=1.
x^y=1, for x=1 and y=2.
x^y=2, for x=2 and y=1.
x^y=4, for x=2 and y=2.
x^y=3, for x=3 and y=1.
x^y=9, for x=3 and y=2.
The conditional mapping of elements of the vector from our previous example, can be solved also using a for
loop:
x = collect(1:10)
y = similar(x) #the object of the same size and type as x
for i ∈ 1:length(x)
y[i] = x[i]%2==0 ? -x[i]^2 : x[i]^2+1
end
println("y=$y")
y=[2, -4, 10, -16, 26, -36, 50, -64, 82, -100]
Instead of using i ∈ 1:length(x)
, we can use (i,xᵢ) ∈ enumerate(x)
.
Using this approach, the for
loop creates one iterator equal to a counter starting at 1
and one iterator xᵢ
equal to subsequent values of x
:
y2 = similar(x)
for (i,xᵢ) ∈ enumerate(x)
y2[i] = xᵢ%2==0 ? -xᵢ^2 : xᵢ^2+1
end
println("y2=$y2")
y2=[2, -4, 10, -16, 26, -36, 50, -64, 82, -100]
The most compact way to perform this operation is to use an inline for
loop.
This type of loops has the following structure [operations for iterator in iterable_object ]
.
In our example this will be:
y = [ xᵢ%2==0 ? -xᵢ^2 : xᵢ^2+1 for xᵢ ∈ x ]
10-element Vector{Int64}:
2
-4
10
-16
26
-36
50
-64
82
-100
I presented several ways of solving the discussed problem.
Personally, I am the biggest fan of using a functional approach involving map
: map(arg -> arg%2==0 ? -arg^2 : arg^2+1 , x)
.
The reason for this is that this approach is easier to be nested inside pipes, discussed later.
while
loops are a traditional alternative to for
loops.
This loop is executed as long as the provided condition is true.
If the condition is not met, then the execution is terminated.
i = 0
while i ≤ 5
println("i=$i")
i+=1;
end
i=0
i=1
i=2
i=3
i=4
i=5
The for
loop can imitate this behavior by combination of break
and conditional statement.
The main difference is that it has the maximum number of iterations equal to the size of the iterable object, in the case below equal to \(1000.\)
i = 0
for κ ∈ 1:1000
println("i=$i")
i+=1;
if i>5 #termination condition
break
end
end
i=0
i=1
i=2
i=3
i=4
i=5
Command break
terminates the current iteration of the loop and executes further code.
In this example we take negation of i≤5
. To directly use this condition, we can use continue
and break
. continue
tells Julia
to finish the current iteration of the loop (in the current line!) and to start a new iteration.
i = 0
for κ ∈ 1:1000
println("i=$i")
i+=1;
if i≤5
continue
else
break
end
1+2+3 #this part of the loop is never executed.
end
i=0
i=1
i=2
i=3
i=4
i=5
Last and maybe the least, we can use short-circuit evaluations discussed here to make the code more compact.
i = 0
for κ ∈ 1:1000
println("i=$i")
i+=1;
i≤5 || break #termination condition. `break` is executed when `i≤5` is false
end
i=0
i=1
i=2
i=3
i=4
i=5