Initializing Tuples

Tuples can be created similarly to arrays, replacing square brackets with parenthesis. For example,

t = (3.14, 2.72)

Creates a variable with type Tuple{Float64, Float64}, whose values can be accessed via t[1] and t[2].

In fact, we don’t even need the parenthesis to initialize a tuple, and simply doing

t = 3.14, 2.72

will work just as well.

Destructuring Tuples

We can cast the elements of a tuple as different variables in a very straightforward manner:

pi_approx, e_approx = t

Tuples are, for this reason, a convenient return type for a function that seemingly returns multiple outputs, such as we discussed in the post about functions.

Converting Tuples to Arrays

Tuples can be converted to arrays in various ways: using the collect function, array comprehensions, or the splat notation.

a = (1, 2, 3)

t1 = collect(a);
t2 = [x for x in a];
t3 = [a...];           

all producing the same output:

3-element Vector{Int64}:

Named Tuples

An interesting variant is that we can assign names to the different elements of a tuple. For example, by declaring

p = ( x = 1.1, y = 2.4)

The elements of p can be accessed via p.x and p.y as well as p[1] and p[2].

p is of type NamedTuple{(:x, :y), Tuple{Float64, Float64}}.

We can also retrieve the names of the keys and the values of a named tuple, using the keys and values functions, as follows:

K = keys(p)                 # (:x, :y)
V = values(p)               # (1.1, 2.4)

and we can merge this key/value pairs into a named tuple again with the zip function:

p_new = (; zip(K,V)...)     # (x = 1.1, y = 2.4)

Since Julia 1.7, there is a new sytnax that can be used to destructure a NamedTuple:

(; y, x) = p

This syntax is equivalent to

y = getproperty(p, :y); 
x = getproperty(p, :x)

so in particular it will generate the new variables regardless of the order in which they are stored or queried.