Julia Tutorial Part 2: Data Structures
Data Structures
In this tutorial, we will see Julia's
data structure. Namely,
- Tuple,
- Array,
- Dictionary, and
- Set
Tuple
Lets first discuss about Tuple
. Tuple and Array can hold a list of elements. But the basic difference between them is, Tuple
is immutable. It means that, we can’t change the value of a tuple once it’s created. We can create a tuple by giving some ordered elements into a paranthesis ( )
. The syntax of a tuple is as follows:
(item1, item2, itme3, ...)
Let’s see an example. Suppose we want to create a tuple consists of some mixed values. We just give those values within a paranthesis ( )
or just without the parenthesis. Both will work just fine. Then we can print the type of the tuple by using the typeof()
method. To access the elements of a tuple, we can use the index values of tuple, but keep in mind in Julia
, index starts from 1. So, in order to access the first element of tuple, we need to follow this syntax:
tuple_name[1]
input
tup1 = (1, 2, 4.5, "Hello")
println(tup1)
#this also works
tup2 = 'c', 11, 0.5, "World"
print(tup2)
output
(1, 2, 4.5, "Hello")
('c', 11, 0.5, "World")
input
println("Type of tup1: ", typeof(tup1))
println("Type of tup2: ", typeof(tup2))
output
Type of tup1: Tuple{Int64,Int64,Float64,String}
Type of tup2: Tuple{Char,Int64,Float64,String}
input
#accessing Elements
println(tup1[1])
println(tup2[end])
output
1
World
As, we were saying earlier that, tuples are immuatble. That means, we can not change the elements of a tuple after it has been initialized. Let’s test that. We will try to change the third element of tup1
. And it will give an error.
input
tup1[3] = 'c'
output
MethodError: no method matching setindex!(::Tuple{Int64,Int64,Float64,String}, ::Char, ::Int64)
Stacktrace:
[1] top-level scope at In[4]:1
There is an another version of tuples and it is called NamedTuples. Here, we can assign an unique name to each elements of the tuple to access them.
To access by using its name we need to use the following syntax:
tuple_name.variable_name
input
named_tup = (lang = 'C', int_num = 1, float_num = 3.6)
println("Elements of named_tuple: ", named_tup)
println("Accessing first element by index: ", named_tup[1])
println("Accessing first element by using variable name: ", named_tup.lang)
output
Elements of named_tuple: (lang = 'C', int_num = 1, float_num = 3.6)
Accessing first element by index: C
Accessing first element by using variable name: C
Array
Unlike Tuples, Arrays are mutable. So, after assigning values we can change them. We can declare an array in many ways. such as:
array_name = [item1, item2, ...]
array_name = Array([item1, item2, ...])
array_name = Array{DataType}([item1, item2, ...])
Here in the third syntax of declaring array, we can specify what kind of data we want to assign in our array. Lets, create three arrays using these syntax.
input
arr1 = [1, 2, 3]
arr2 = Array([2.5, "Hello", 100])
arr3 = Array{Int64}([4, 6, 8])
println("Elements of arr1: ", arr1)
println("Elements of arr2: ", arr2)
println("Elements of arr3: ", arr3)
output
Elements of arr1: [1, 2, 3]
Elements of arr2: Any[2.5, "Hello", 100]
Elements of arr3: [4, 6, 8]
These are the example of 1 dimensional array. The syntax of declaring 2 dimensional array is follows:
array_2d = [item1 item2; item3 item4; ...]
Let’s create an array which has 3 row and 2 columns or an (3*2)
array.
input
arr_2d =[1 2; 3 4; 5 6]
arr_2d
output
3×2 Array{Int64,2}:
1 2
3 4
5 6
Array Operations
To insert, delete or sort elements of an array we can use some built in methods like insert(), deleteat(), push(), pushfirst(), pop(), popfirst(), sort()
. Let’s use these methods. To insert elements in an array we can use push()
, pushfirst()
and insert()
methods. push()
method insert an element in the end of the array, pushfirst()
inserts an item at the begining of the array, and insert()
method insert an item into a given location. The syntax of insert()
method is
insert(arr_name, position_to_insert, value)
Let’s first insert into an array.
input
test_arr = [1, 2, 3, 4, 5]
push!(test_arr, 100)
println("Array after using push method: ", test_arr)
pushfirst!(test_arr, 12)
println("Array after using pushfirst method: ", test_arr)
insert!(test_arr, 3, 2525)
println("Array after using insert method: ", test_arr)
output
Array after using push method: [1, 2, 3, 4, 5, 100]
Array after using pushfirst method: [12, 1, 2, 3, 4, 5, 100]
Array after using insert method: [12, 1, 2525, 2, 3, 4, 5, 100]
To delete elements in an array, we can use pop()
, popfirst()
and deleteat()
methods. pop()
method deletes an element from the end of the array, popfirst()
deletes an item from the begining of the array, and deleteat()
method deletes an item from a given location. The syntax of deleteat()
method is
deleteat(arr_name, position_for_delete)
We will use the same array which we used with insertion methods.
input
println("Array before deleting elements: ", test_arr)
pop!(test_arr)
println("Array after using pop method: ", test_arr)
popfirst!(test_arr)
println("Array after using popfirst method: ", test_arr)
deleteat!(test_arr, 4)
println("Array after using deleteat method at the 4th index: ", test_arr)
output
Array before deleting elements: [12, 1, 2525, 2, 3, 4, 5, 100]
Array after using pop method: [12, 1, 2525, 2, 3, 4, 5]
Array after using popfirst method: [1, 2525, 2, 3, 4, 5]
Array after using deleteat method at the 4th index: [1, 2525, 2, 4, 5]
Besides these inserting and deletion methods, there are some methods for other helpful tasks. Here, we will try to mention some of the methods. For sorting we can use sort()
method. Also, if we want arrays of ones or zeros we can use ones()
and zeros()
method respectively. We can generate random number from uniform distribution using rand()
method. To create random number from normal distribution we can use randn()
method.
Let’s see them in action.
input
# sorting test_arr
println("Before sorting the test_array: ", test_arr)
sort!(test_arr)
println("After sorting the test_array: ", test_arr)
output
Before sorting the test_array: [1, 2525, 2, 4, 5]
After sorting the test_array: [1, 2, 4, 5, 2525]
input
# create an 2*3 array of ones
ones_arr = ones(2, 3)
ones_arr
output
2×3 Array{Float64,2}:
1.0 1.0 1.0
1.0 1.0 1.0
input
# create an 2*3 array of zeros
zeros_arr = zeros(2, 3)
zeros_arr
output
2×3 Array{Float64,2}:
0.0 0.0 0.0
0.0 0.0 0.0
input
# create an array size of 2*5 with random variable from uniform distribution
rand(2, 5)
output
2×5 Array{Float64,2}:
0.451961 0.309916 0.193709 0.602781 0.160294
0.737481 0.523093 0.662101 0.946056 0.804512
input
# create an array size of 2*5 with random variable from normal distribution
randn(2, 5)
output
2×5 Array{Float64,2}:
0.907519 2.42625 0.909603 -0.420501 0.632623
-1.78817 0.63605 0.17628 0.419475 -0.200928
Dictionary
Dictionary is a collection of key-value pairs, where we can access the value using its key. We can declare dictionary in the following three ways:
dict_name = Dict()
dict_name = Dict(key1 => value1, key2 => value2, ....)
dict_name = Dict{key_datatype, value_datatype}(key1 => value1, key2 => value2, ....)
Here in the third syntax of declaring dictionary, we can specify the data types of keys and values.
input
dict1 = Dict()
dict1["Bangladesh"] = "Dhaka"
dict1["Sweden"] = "Stockholm"
println("Elements of dict1: ", dict1)
dict2 = Dict("Apple" => "Red", "Orange" => "Orange", "Banana" => "Yellow")
println("Elements of dict2: ", dict2)
dict3 = Dict{String, Int64}("One" => 1, "Two" => 2, "Three" => 3)
println("Elements of dict3: ", dict3)
output
Elements of dict1: Dict{Any,Any}("Bangladesh" => "Dhaka","Sweden" => "Stockholm")
Elements of dict2: Dict("Apple" => "Red","Orange" => "Orange","Banana" => "Yellow")
Elements of dict3: Dict("One" => 1,"Two" => 2,"Three" => 3)
Accessing Dictionary Elements
To access the elements of dictionary we need to access them via their key. Suppose in dict3
, we want to access the value 3
. So, we can do that by this:
input
println(dict3["Three"])
output
3
Also, we can access the keys and values of a dictionary seperately by using keys()
and values()
method respectively.
input
println("Keys of dict3: ", keys(dict3))
println("Values of dict3: ", values(dict3))
output
Keys of dict3: ["One", "Two", "Three"]
Values of dict3: [1, 2, 3]
Set
Another data structure of julia
is set
. Set
is like array
, its mutable. But the basic difference between them is, set
holds only unique element
. So, there will be no duplicate element in a set
. And the basic syntax of a set is:
set_name = Set([item1, item2, item3, ....])
We can do operations like union, intersection, difference between two sets using union()
, intersect()
, and setdiff()
methods respectively. Also we can check if one set is subset of another one by using issubset()
function.
Here we will create 2 sets and apply these functions on them.
input
set1 = Set([1, 2, 3, 2, 5, "new"])
println("Set1: ", set1)
set2 = Set([5, 2])
println("Set1: ", set2)
output
Set1: Set(Any["new", 2, 3, 5, 1])
Set1: Set([2, 5])
input
# union between two sets
union(set1, set2)
output
Set{Any} with 5 elements:
"new"
2
3
5
1
input
# intersection between two sets
intersect(set1, set2)
output
Set{Any} with 2 elements:
2
5
input
# set difference between two sets
setdiff(set1, set2)
output
Set{Any} with 3 elements:
"new"
3
1
input
# Checking if set2 is subset of set1
issubset(set2, set1)
output
true
As, set is mutable, we can add or delete elements from it. To add elements we can use push()
method and to delete elements we can use delete()
method. For deletion, we need to tell specifically which element from a set we want to delete.
input
push!(set1, "hello")
output
Set{Any} with 6 elements:
"new"
2
3
"hello"
5
1
input
delete!(set1, "hello")
output
Set{Any} with 5 elements:
"new"
2
3
5
1
So, thats it.
Keep Practicing.
Good luck, May the Julia be with you!!
Other posts in this series: