Одномерные массивы (векторы)
В Julia одномерный массив называется вектором. Тип Vector{T}
и Array{T,1}
, где T
- один и тот же тип, взаимозаменяемы:
julia> Array{Int64,1} <: Vector{Int64} # одномерный массив - это вектор того же типа
true
julia> Vector{Int64} <: Array{Int64,1} # вектор типа Int - это одномерный массив Int
true
julia> Vector <: Array # вектор - это массив
true
julia> Array <: Vector # но не всякий массив - вектор
false
В программах, везде, где ожидается одномерный массив, можно писать Vector
для краткости, или с указанием типа, например, Vector{Int}
. Это синонимы.
Самый интуитивный способ создания массива - через определение его элементов. Тут можно сразу обратить внимание, как выводятся типы этих массивов при создании:
julia> a1 = [3,4,5] # в этот массив позже нельзя будет добавить строку
3-element Array{Int64,1}:
3
4
5
julia> a2 = ["a","bc"] # здесь - стого строки
2-element Array{String,1}:
"a"
"bc"
julia> a3 = ["a","bc", 42] # а этот - позволит любой тип в дальнейшем
3-element Array{Any,1}:
"a"
"bc"
42
когда автоматический вывод типов не устраивает, можно указать тип явно:
Any[3,4,5]
3-element Array{Any,1}:
3
4
5
перед квадратными скобками можно использовать любой тип, даже собственный:
julia> immutable Mytype x::Int end
julia> Mytype[]
0-element Array{Mytype,1}
Обозначения Array{Int64,1}, Array{String,1}, Array{Any,1} - это типы массивов. Единичка в них - это размерность. В данном случае это простые массивы (размерностью 1), в которых конкретный элемент будет определяться одним индексом (не двумя, не тремя и.т.д.).
Экземпляр пустого массива можно создать, вызвав конструктор на любом из этих типов:
julia> empty_any_array = Array{Any,1}()
0-element Array{Any,1}
обратите внимание на круглые скобки, без них вы получите не экземпляр, а тип: переменная empty_any_array
будет содержать тип. Такое возможно, потому что в Julia типы - это равноправные объекты, которые можно передавать, как значение (как переменные и функции).
Иногда, для повышения производительности кода, требуется заранее выделить память под массив - это когда размер массива задан (память выделена), но элементы не инициализированы. Это делается в вышеприведенном синтаксисе с указанием количества (неинициализированных) элементов в круглых скобках:
julia> empty_a3 = Array{Any,1}(2)
2-element Array{Any,1}:
#undef
#undef
в этом массиве первые два элемента уже доступны:
empty_a3[1]="asd"
а, добавленный новый элемент будет иметь индекс 3:
julia> push!(empty_a3,1)
3-element Array{Any,1}:
"asd"
#undef
1
Создание массива синтаксисом спискового включения.
Общий синтаксис:
A = [ F(x,y,...) for x=rx, y=ry, ... ]
Например:
julia> [x*2 for x in 1:3]
3-element Array{Int64,1}:
2
4
6
можно указать тип вручную:
julia> Float32[x*2 for x in 1:3]
3-element Array{Float32,1}:
2.0
4.0
6.0
Диапазоны
Это простой, но полезный тип данных. Диапазон хранит только границы и шаг.
Первый способ создания - с помощью функции range (первый элемент, [шаг,] количество элементов)
:
julia> range( 5,1,6)
5:1:10
julia> range( 5,6)
5:10
julia> range( 5,1,6)|>collect
6-element Array{Int64,1}:
5
6
7
8
9
10
julia> range( 5,6)|>collect
6-element Array{Int64,1}:
5
6
7
8
9
10
Второй способ - синтаксисом создания диапазона, где указываются его границы и шаг:
julia> 5:1:10
5:1:10
julia> 5:1:10|>collect
6-element Array{Int64,1}:
5
6
7
8
9
10
В обоих случаях можно указать шаг, отличный от единицы:
julia> range( 5,2,6)|>collect
6-element Array{Int64,1}:
5
7
9
11
13
15
julia> 5:2:15 |> collect
6-element Array{Int64,1}:
5
7
9
11
13
15
Конечно же, массивы и интервалы являются итерируемыми объектами:
julia> a = [3,4,5,6,7];
julia> for i in a
println(i)
end
3
4
5
6
7
julia> b= 3:7;
julia> for i in b
println(i)
end
3
4
5
6
7