یکی از اهداف اصلی Julia این است که بتواند محاسبات را روی دادههای عددی، سریع و کارآمد انجام دهد. کلی دادهی عددی.
معمولاً این دادهها در آرایهها (یا نوع مرتبط دیگری) ذخیره میشوند، بنابراین میتوان گفت که آرایهها در قلب زبان Julia قرار دارند.
آرایهها میتوانند اندازهی دلخواه داشته باشند (فقط محدود به حافظهی سختافزار شما) و میتوانند هر تعداد بُعد داشته باشند.
این مفهوم مقدماتی بر مبانی آرایههای یکبعدی تمرکز دارد، که به آنها Vector میگویند.
Vector
در Julia، یک Vector دنبالهی مرتبی از مقادیر است که میتوان با شمارهی اندیس به آنها دسترسی داشت.
سادهترین راه برای ساختن یک Vector این است که مقادیر را داخل کروشه فهرست کنید:
julia> num_vec = [1, 4, 9]
3-element Vector{Int64}:
1
4
9
julia> str_vec = ["arrays", "are", "important"]
3-element Vector{String}:
"arrays"
"are"
"important"
نوع Vector با نوع هر عنصر مطابقت دارد.
یعنی Vectorها باید همگن باشند (همهی عناصر از یک نوع)؟
تا حدی بله، و اگر بهترین کارایی را میخواهید توصیه میشود همین را هدف بگیرید.
با این حال، Julia میتواند (در صورت لزوم) با استفاده از نوع Any این محدودیت را دور بزند:
julia> mixed_vector = [1, "str", 'c']
3-element Vector{Any}:
1
"str"
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
هنگام ساختن یک Vector خالی، Julia بهطور پیشفرض نوع عنصر را Any در نظر میگیرد، اما میتوان با حاشیهنویسی آرایهی خالی با نوع عنصر موردنظر، آن را دقیقتر تعریف کرد.
julia> empty_vec = []
Any[]
julia> empty_int_vec = Int64[]
Int64[]
لطفاً این قاعده را بخوانید و به خاطر بسپارید:
این برای هر کسی که از زبانهای دیگر علم داده (R، Matlab، Fortran...) استفاده کرده باشد آشناست، اما ممکن است برای دانشمندان رایانهای با پیشینهی زبانهای شبیه C تکاندهنده به نظر برسد.
در غیر این صورت، اندیسها همانطور که حدس میزنید کار میکنند: کافی است آنها را داخل کروشه بگذارید:
squares = [0, 1, 4, 9, 16]
squares[1] # 0
squares[3] # 4
squares[begin] # 0 ("begin" is synonym for 1)
squares[end] # 16 ("end" is synonym for length(squares))
به سادگیِ اندیسگذاری با end (که بسیار مفید است) و begin (که احتمالاً نیست) توجه کنید.
برنامهنویسان Python ممکن است دربارهی اندیسهای منفی کنجکاو باشند.
دنبالشان نگردید: اینها بخشی از Julia نیستند و باعث خطای BoundsError میشوند، همانطور که هر اندیسی کوچکتر از ۱ یا بزرگتر از length(squares) چنین میکند.
Vector
Vectorها در Julia تغییرپذیر هستند: میتوانیم محتویات خانههای تکتک را تغییر دهیم.
julia> vals = [1, 3, 5, 7]
4-element Vector{Int64}:
1
3
5
7
julia> vals[2] = 4 # reassign the value of this element
4
# Only the value at position 2 changes:
julia> vals
4-element Vector{Int64}:
1
4
5
7
توابع زیادی برای دستکاری Vectorها در دسترس است، هرچند مستندات Julia آنها را بهجای بردار به «مجموعهها» تعمیم میدهد.
توجه کنید که بنا بر قرارداد، توابعی که ورودی خود را تغییر میدهند در اسمشان ! دارند.
کامپایلر این را اجبار نمیکند، اما در دنیای Julia یک قرارداد بسیار قوی است.
اینها چند تا از توابع مفید هستند:
Vector، از push!() استفاده کنید.pop!() استفاده کنید.Vector، توابع متناظر pushfirst!() و popfirst!() هستند.insert!() و deleteat!() وجود دارند.julia> vals = [1, 3]
2-element Vector{Int64}:
1
3
julia> push!(vals, 5, 6) # can add multiple values
4-element Vector{Int64}:
1
3
5
6
julia> pop!(vals) # mutates vals, return popped value
6
julia> vals
3-element Vector{Int64}:
1
3
5
الیس بهعنوان یک شعبدهباز تازهکار باید چند مقدمه را تمرین کند. او یک دسته کارت دارد که میخواهد آنها را دستکاری کند.
برای اینکه کار کمی سادهتر شود، فقط از کارتهای ۱ تا ۱۰ استفاده میکند، بنابراین دستهی کارتهایش را میتوان با یک بردار از اعداد نمایش داد. موقعیت یک کارت مشخص با اندیس آن در بردار متناظر است.
برای برداشتن یک کارت، کارت واقع در اندیس position را از دستهی دادهشده برگردانید.
julia> stack = [1, 2, 4, 1];
julia> position = 3;
julia> get_item(stack, position)
4
کمی تردستی کنید و کارت واقع در اندیس position را با کارت جایگزینی که داده شده است عوض کنید.
دستهی تغییردادهشده را برگردانید.
julia> stack = [1, 2, 4, 1];
julia> position = 3;
julia> replacement_card = 6;
julia> set_item!(stack, position, replacement_card)
[1, 2, 6, 1]
با درج یک کارت جدید در بالای دسته، کارتی را ظاهر کنید. دستهی تغییردادهشده را برگردانید.
julia> stack = [5, 9, 7, 1];
julia> new_card = 8;
julia> insert_item_at_top!(stack, new_card)
[5, 9, 7, 1, 8]
با حذف کارت واقع در position دادهشده از دسته، کارتی را ناپدید کنید.
دستهی تغییردادهشده را برگردانید.
julia> stack = [3, 2, 6, 4, 8];
julia> position = 3;
julia> remove_item!(stack, position)
[3, 2, 4, 8]
با حذف کارت بالای دسته، کارتی را ناپدید کنید. دستهی تغییردادهشده را برگردانید.
julia> stack = [3, 2, 6, 4, 8];
julia> remove_item_from_top!(stack)
[3, 2, 6, 4]
با درج یک کارت جدید در پایین دسته، کارتی را ظاهر کنید. دستهی تغییردادهشده را برگردانید.
julia> stack = [5, 9, 7, 1];
julia> new_card = 8;
julia> insert_item_at_bottom!(stack, new_card)
[8, 5, 9, 7, 1]
با حذف کارت پایین دسته، کارتی را ناپدید کنید. دستهی تغییردادهشده را برگردانید.
julia> stack = [8, 5, 9, 7, 1];
julia> remove_item_at_bottom!(stack)
[5, 9, 7, 1]
بررسی کنید که اندازهی دسته با stack_size برابر است یا نه.
julia> stack = [3, 2, 6, 4, 8];
julia> stack_size = 4;
julia> check_size_of_stack(stack, stack_size)
false