print and println@printftry-catch for Exception HandlingfinallyManipulating arrays, such as changing their contents, adding or removing items, or reorganizing them, is a common task. Julia provides a comprehensive set of built-in functions to work with arrays effectively. Many of these functions modify the array directly. Functions that modify their arguments often have names ending with an exclamation mark (!) in Julia. This is a helpful convention that signals the function will alter the data it's given, rather than returning a new, modified copy.
Growing your array with new data is a common requirement. Julia offers several ways to add elements:
push!(array, item): Adds item to the end of the array. This is one of the most common ways to append a single element.
julia> numbers = [10, 20, 30]
3-element Vector{Int64}:
10
20
30
julia> push!(numbers, 40)
4-element Vector{Int64}:
10
20
30
40
julia> numbers
4-element Vector{Int64}:
10
20
30
40
Notice how numbers itself has changed.
append!(array, collection): Adds all elements from collection to the end of array. This is useful when you want to merge another array (or any iterable collection) into your existing one.
julia> list_a = [1, 2]
2-element Vector{Int64}:
1
2
julia> list_b = [3, 4, 5]
3-element Vector{Int64}:
3
4
5
julia> append!(list_a, list_b)
5-element Vector{Int64}:
1
2
3
4
5
julia> list_a
5-element Vector{Int64}:
1
2
3
4
5
prepend!(array, collection): Adds all elements from collection to the beginning of array.
julia> scores = [85, 92]
2-element Vector{Int64}:
85
92
julia> prepend!(scores, [70, 78])
4-element Vector{Int64}:
70
78
85
92
insert!(array, index, item): Inserts item at the specified index, shifting subsequent elements to the right.
julia> letters = ['a', 'c', 'd']
3-element Vector{Char}:
'a'
'c'
'd'
julia> insert!(letters, 2, 'b') # Insert 'b' at index 2
4-element Vector{Char}:
'a'
'b'
'c'
'd'
The following diagram illustrates how push! adds an element to the end of an array, and insert! adds an element at a specific position.
The diagram shows an initial array
items.push!appends an element, whileinsert!places a new element at a specified index, moving existing elements.
Just as you can add elements, you can also remove them:
pop!(array): Removes and returns the last element from array.
julia> stack = ["task1", "task2", "task3"]
3-element Vector{String}:
"task1"
"task2"
"task3"
julia> last_task = pop!(stack)
"task3"
julia> println(last_task)
task3
julia> stack
2-element Vector{String}:
"task1"
"task2"
popfirst!(array): Removes and returns the first element from array.
julia> queue = ["A", "B", "C"]
3-element Vector{String}:
"A"
"B"
"C"
julia> first_item = popfirst!(queue)
"A"
julia> queue
2-element Vector{String}:
"B"
"C"
deleteat!(array, index_or_range): Removes the element at the specified index or elements within a range.
julia> data = [10, 20, 30, 40, 50]
5-element Vector{Int64}:
10
20
30
40
50
julia> deleteat!(data, 3) # Remove element at index 3 (which is 30)
4-element Vector{Int64}:
10
20
40
50
julia> deleteat!(data, 2:3) # Remove elements at index 2 and 3 (now 20 and 40)
2-element Vector{Int64}:
10
50
empty!(array): Removes all elements from array, making it empty.
julia> temp_list = [1, 2, 3]
3-element Vector{Int64}:
1
2
3
julia> empty!(temp_list)
0-element Vector{Int64}
julia> temp_list
0-element Vector{Int64}
splice!(array, index_or_range, [replacement_collection]): This is a versatile function. It removes element(s) at index_or_range and returns them. Optionally, it can insert elements from replacement_collection at that position.
julia> letters = ['a', 'b', 'x', 'y', 'c', 'd']
6-element Vector{Char}:
'a'
'b'
'x'
'y'
'c'
'd'
julia> removed = splice!(letters, 3:4) # Remove elements at index 3 and 4
2-element Vector{Char}:
'x'
'y'
julia> letters # 'x' and 'y' are gone
4-element Vector{Char}:
'a'
'b'
'c'
'd'
julia> values = [10, 20, 99, 100, 50]
5-element Vector{Int64}:
10
20
99
100
50
julia> old_values = splice!(values, 3:4, [30, 40]) # Remove 99, 100 and insert 30, 40
2-element Vector{Int64}:
99
100
julia> values
5-element Vector{Int64}:
10
20
30
40
50
Often, you need to find out information about an array without changing it:
length(array): Returns the number of elements in the array.
julia> mixed_bag = [1, "hello", 3.14]
3-element Vector{Any}:
1
"hello"
3.14
julia> length(mixed_bag)
3
size(array): Returns a tuple containing the dimensions of the array. For a one-dimensional array (a vector), it returns a 1-tuple (length,).
julia> vec = [1, 2, 3, 4]
4-element Vector{Int64}:
1
2
3
4
julia> size(vec)
(4,)
julia> matrix = [1 2; 3 4] # A 2x2 matrix
2×2 Matrix{Int64}:
1 2
3 4
julia> size(matrix)
(2, 2)
isempty(array): Returns true if the array has no elements, and false otherwise.
julia> empty_arr = []
0-element Vector{Any}
julia> isempty(empty_arr)
true
julia> non_empty_arr = [1]
1-element Vector{Int64}:
1
julia> isempty(non_empty_arr)
false
in(item, collection) (or item ∈ collection): Checks if item is present in collection. Returns true or false.
julia> fruits = ["apple", "banana", "cherry"]
3-element Vector{String}:
"apple"
"banana"
"cherry"
julia> "banana" in fruits
true
julia> "grape" in fruits
false
julia> "apple" ∈ fruits # You can type ∈ by typing \in then pressing Tab
true
findfirst(predicate, array): Returns the index of the first element in array for which the predicate function returns true. If no such element is found, it returns nothing. A predicate is simply a function that takes an element and returns true or false.
julia> numbers = [10, 25, 30, 45, 50]
5-element Vector{Int64}:
10
25
30
45
50
julia> findfirst(x -> x > 30, numbers) # Find first number greater than 30
4 # Index of 45
julia> findfirst(iseven, numbers) # `iseven` is a built-in predicate
1 # Index of 10
julia> findfirst(x -> x > 100, numbers) # Nothing will be printed, returns `nothing`
findall(predicate, array): Returns a vector of indices for all elements in array for which the predicate function returns true.
julia> data = [1, 0, 2, 0, 3, 0, 4]
7-element Vector{Int64}:
1
0
2
0
3
0
4
julia> findall(x -> x == 0, data) # Find all zeros
3-element Vector{Int64}:
2
4
6
You can also create new arrays based on existing ones or reorder them:
sort(array) and sort!(array):
sort(array) returns a new array with elements sorted. The original array is unchanged.sort!(array) sorts the array in-place, modifying the original array.julia> unsorted_nums = [3, 1, 4, 1, 5, 9, 2, 6]
8-element Vector{Int64}:
3
1
4
1
5
9
2
6
julia> sorted_copy = sort(unsorted_nums)
8-element Vector{Int64}:
1
1
2
3
4
5
6
9
julia> unsorted_nums # Original is unchanged
8-element Vector{Int64}:
3
1
4
1
5
9
2
6
julia> sort!(unsorted_nums) # Sorts in-place
8-element Vector{Int64}:
1
1
2
3
4
5
6
9
julia> unsorted_nums # Original is now sorted
8-element Vector{Int64}:
1
1
2
3
4
5
6
9
You can also sort in reverse order: sort(array, rev=true).
reverse(array) and reverse!(array):
reverse(array) returns a new array with elements in reverse order.reverse!(array) reverses the array in-place.julia> items = [10, 20, 30, 40]
4-element Vector{Int64}:
10
20
30
40
julia> reversed_copy = reverse(items)
4-element Vector{Int64}:
40
30
20
10
julia> items # Original is unchanged
4-element Vector{Int64}:
10
20
30
40
julia> reverse!(items)
4-element Vector{Int64}:
40
30
20
10
julia> items # Original is now reversed
4-element Vector{Int64}:
40
30
20
10
map(function, array): Applies function to each element of array and returns a new array containing the results.
julia> numbers = [1, 2, 3, 4]
4-element Vector{Int64}:
1
2
3
4
julia> squares = map(x -> x^2, numbers)
4-element Vector{Int64}:
1
4
9
16
filter(predicate, array): Returns a new array containing only the elements of array for which predicate returns true.
julia> values = [10, 15, 20, 25, 30, 35]
6-element Vector{Int64}:
10
15
20
25
30
35
julia> even_values = filter(iseven, values)
3-element Vector{Int64}:
10
20
30
Julia provides convenient ways to combine multiple arrays:
vcat(arrays...): Vertically concatenates arrays. For vectors (1D arrays), this stacks them one after another into a new, longer vector. You can also use the semicolon syntax [array1; array2; ...] for this.
julia> arr1 = [1, 2]
2-element Vector{Int64}:
1
2
julia> arr2 = [3, 4, 5]
3-element Vector{Int64}:
3
4
5
julia> combined_v = vcat(arr1, arr2)
5-element Vector{Int64}:
1
2
3
4
5
julia> also_combined_v = [arr1; arr2] # Same as vcat
5-element Vector{Int64}:
1
2
3
4
5
hcat(arrays...): Horizontally concatenates arrays. For vectors, this places them side-by-side to form a 2D array (a matrix). The syntax [array1 array2 ...] (using spaces) also performs horizontal concatenation.
julia> col1 = [10, 20]
2-element Vector{Int64}:
10
20
julia> col2 = [30, 40]
2-element Vector{Int64}:
30
40
julia> combined_h = hcat(col1, col2)
2×2 Matrix{Int64}:
10 30
20 40
julia> also_combined_h = [col1 col2] # Same as hcat
2×2 Matrix{Int64}:
10 30
20 40
Note: If using
hcator space-separated syntax with 1D arrays of different lengths, you'll get an error. They must have compatible dimensions for horizontal concatenation into a matrix.
copy and deepcopyWhen you assign an array to a new variable, you are not creating a new array. Instead, both variables point to the same array in memory. Modifying the array through one variable will affect the other.
julia> original_list = [1, 2, 3]
3-element Vector{Int64}:
1
2
3
julia> same_list = original_list # Both variables point to the same array
3-element Vector{Int64}:
1
2
3
julia> push!(same_list, 4)
4-element Vector{Int64}:
1
2
3
4
julia> original_list # Original_list is also modified!
4-element Vector{Int64}:
1
2
3
4
To create an independent copy, Julia provides copy and deepcopy:
copy(array): Creates a shallow copy. The new array is a distinct object, but if the array contains other mutable collections (like arrays within an array), those inner collections are still shared. For arrays of simple types like numbers or strings, copy is often sufficient.
julia> a = [1, 2, 3]
3-element Vector{Int64}:
1
2
3
julia> b = copy(a)
3-element Vector{Int64}:
1
2
3
julia> push!(b, 4)
4-element Vector{Int64}:
1
2
3
4
julia> a # `a` is unchanged
3-element Vector{Int64}:
1
2
3
deepcopy(array): Creates a deep copy. The new array and everything it contains (including nested arrays or other mutable objects) are recursively copied. This ensures complete independence.
julia> nested_original = [[1, 2], [3, 4]]
2-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]
julia> shallow_copy = copy(nested_original)
2-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]
julia> deep_copied = deepcopy(nested_original)
2-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]
# Modify an inner array through the shallow copy
julia> push!(shallow_copy[1], 99)
3-element Vector{Int64}:
1
2
99
julia> nested_original # The original is affected by the shallow copy modification!
2-element Vector{Vector{Int64}}:
[1, 2, 99]
[3, 4]
julia> deep_copied # The deep copy remains independent
2-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]
Understanding the difference between shallow and deep copies is important for avoiding unintended side effects when working with arrays that contain other mutable structures.
These functions provide a powerful toolkit for manipulating arrays. As you work more with Julia, you'll find these operations become second nature for cleaning, transforming, and preparing your data.
Was this section helpful?
push!, append!, pop!, deleteat!, and splice!, explaining Julia's convention for mutating functions.length, size, isempty), searching elements (findfirst, findall), combining arrays (vcat, hcat), and general transformations like map and filter.© 2026 ApX Machine LearningEngineered with