آرایه یک ساختار دادهی تغییرپذیر است که مجموعهای از عنصرها از یک نوع مشخص را ذخیره میکند. آرایه یک ساختار دادهی ایندکسپذیر است. تغییرپذیر بودن آرایهها یعنی اگر متدی روی آرایه فراخوانی شود که آن را تغییر میدهد، خود آرایه تغییر میکند. یعنی آرایهی جدیدی ساخته نمیشود، بلکه همان آرایهی موجود تغییر میکند.
برای ساختن آرایه، از نحوهی نگارش نوشتار آرایه ([]) استفاده کنید و درون آن، عنصرهای آرایه را با کاما از هم جدا کنید.
[1, 2, 3] # => [1, 2, 3]
Crystal نوع آرایه را از روی عنصرها استنتاج میکند.
[1, 2, 3].class # => Array(Int32)
با اینکه پیشتر گفتیم آرایه مجموعهای از عنصرها از یک نوع مشخص است، میتوانید با استفاده از نوعهای اتحادی آرایهای با چند نوع بسازید. این کار باعث میشود آرایه بتواند عنصرهایی از هر یک از نوعهای نامبرده در نوع اتحادی را در خود جای دهد. Crystal نوع آرایه را از روی عنصرها استنتاج میکند.
[1, "2", 3.0] # => [1, "2", 3.0]
[1, "2", 3.0].class # => Array(Int32 | Float64 | String)
آرایهی چندبعدی آرایهای از آرایهها است.
یعنی هر عنصر آن آرایه، خودش یک آرایه است.
این میتواند زمانی مفید باشد که بخواهید دادهها را در قالب یک جدول ذخیره کنید.
برای تعریف یک آرایهی چندبعدی، میتوانید نوشتار آرایهای از آرایهها را بنویسید یا از سازندهی Array.new استفاده کنید.
[[1, 2], [3, 4]] # => [[1, 2], [3, 4]]
numbers = Array(Array(Int32)).new() # => []
numbers << [1, 2] # => [[1, 2]]
برای افزودن عنصر به یک آرایه، از عملگر << (افزودن) استفاده کنید.
[1, 2, 3] << 4 # => [1, 2, 3, 4]
نوع عنصری که میخواهید اضافه کنید باید همانند نوع آرایه باشد؛ در غیر این صورت خطایی ایجاد میشود.
numbers : Array(Int32 | Float64) = [1, 2, 3]
numbers << 4.0
numbers # => [1, 2, 3, 4.0]
numbers << "5" # => Error: no overload matches 'Array(Int32 | Float64)#<<' with type String
مانند String، میتوانید اندازهی یک آرایه را با استفاده از متد size به دست آورید.
[1, 2, 3].size # => 3
کامپایلر هنگام ساختن آرایهی خالی نمیتواند نوع آرایه را استنتاج کند.
بنابراین باید نوع آرایه را مشخص کنید.
این کار با تعیین نوع آرایه، با استفاده از کلیدواژهی of، یا با استفاده از نحوهی نگارش سازندهی آرایه، یعنی Array(T).new، انجام میشود.
[] of (Int32 | Float64 | String) # => []
Array(Int32 | Float64 | String).new # => []
مانند String، میتوانید با استفاده از عملگر [] (ایندکس) و دادن ایندکس عنصری که میخواهید به آن دسترسی پیدا کنید، به عنصرهای یک آرایه دسترسی داشته باشید.
اگر ایندکس خارج از محدوده باشد، یک IndexError ایجاد میشود.
[1, 2, 3][0] # => 1
[1, 2, 3][3] # => Index out of bounds (IndexError)
همچنین میتوان با استفاده از یک بازه به عنصرها دسترسی داشت.
[1, 2, 3][0..1] # => [1, 2]
برای ساختن آرایه از یک بازه، از متد to_a استفاده کنید.
این کار زمانی مفید است که بخواهید آرایهای از اعداد بسازید.
(1..3).to_a # => [1, 2, 3]
برای ساختن آرایه از یک رشته، از متد split استفاده کنید.
این متد به شما امکان میدهد یک رشته را با استفاده از یک جداکننده به آرایهای از رشتهها تقسیم کنید.
"1,2,3".split(",") # => ["1", "2", "3"]
همچنین میتوان با استفاده از متد chars آرایهای از کاراکترها را از یک رشته به دست آورد.
"123".chars # => ['1', '2', '3']
برای تبدیل آرایهای از Char یا String به یک String میتوانید از متد join استفاده کنید که یک جداکننده را به عنوان آرگومان میگیرد.
['1', '2', '3'].join(".") # => "1.2.3"
وقتی میخواهید عنصری را از انتهای آرایه حذف کنید، میتوانید از متد pop استفاده کنید که یک آرگومان اختیاری میگیرد و مشخص میکند چند عنصر از انتهای آرایه حذف شود.
این متد عنصر حذفشده را برمیگرداند.
اگر آرایه خالی باشد، یک IndexError ایجاد میشود.
numbers = [1, 2, 3]
numbers.pop # => 3
numbers # => [1, 2]
empty_numbers = [] of Int32
empty_numbers.pop # => Index out of bounds (IndexError)
وقتی میخواهید عنصری با ایندکس مشخص را از آرایه حذف کنید، میتوانید از متد delete_at استفاده کنید که ایندکس عنصر موردنظر برای حذف را به عنوان آرگومان میگیرد.
اگر آرایه خالی باشد، یک IndexError ایجاد میشود.
numbers = [1, 2, 3]
numbers.delete_at(1) # => 2
numbers # => [1, 3]
empty_numbers = [] of Int32
empty_numbers.delete_at(0) # => Index out of bounds (IndexError)
وقتی میخواهید عنصری با ایندکس مشخص را در آرایه تغییر دهید، میتوانید از عملگر []= (انتساب ایندکس) استفاده کنید که ایندکس عنصر موردنظر و مقدار جدید را به عنوان آرگومان میگیرد.
اگر ایندکس خارج از محدوده باشد، یک IndexError ایجاد میشود.
numbers = [1, 2, 3]
numbers[1] = 4
numbers # => [1, 4, 3]
numbers[3] = 5 # => Index out of bounds (IndexError)
در این تمرین باید چند متد پیادهسازی کنید تا یک آرایه از زبانهای برنامهنویسی را دستکاری کنید.
متد LanguageList.list را تعریف کنید که هیچ آرگومانی نمیگیرد و یک آرایهی خالی از نوع Array(String) برمیگرداند.
LanguageList.list()
# => []
متد LanguageList.add را تعریف کنید که ۲ آرگومان میگیرد (یک آرایهی زبانها و یک رشتهی متنی از یک زبان).
این متد باید آرایه را همراه با زبان جدیدی که به انتهای آن اضافه شده است برگرداند.
language_list = LanguageList.list()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]
متد LanguageList.remove را تعریف کنید که ۱ آرگومان میگیرد (یک آرایهی زبانها).
این متد باید آرایه را بدون آخرین عنصر برگرداند.
فرض کنید آرایه همیشه حداقل یک عنصر دارد.
language_list = LanguageList.list()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]
language_list = LanguageList.remove(language_list)
# => ["Crystal"]
تابع LanguageList.at را تعریف کنید که ۲ آرگومان میگیرد (یک آرایهی زبانها و یک اندیس).
این متد باید زبانی را که در اندیس n آرایه قرار دارد برگرداند.
فرض کنید همیشه در آن اندیس یک زبان وجود دارد.
language_list = LanguageList.new()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]
LanguageList.at(language_list, 1)
# => "Ruby"
متد LanguageList.parse را تعریف کنید که ۱ آرگومان میگیرد (یک رشتهی متنی از زبانها که با کاما از هم جدا شدهاند).
این متد باید آرایهای از زبانها برگرداند.
LanguageList.parse("Crystal, Ruby")
# => ["Crystal", "Ruby"]