語言清單

語言清單

學習練習

簡介

陣列 是一種可變的資料結構,用於儲存特定型別元素的集合。 陣列是一種可索引的資料結構。 陣列可變的意思是,如果對陣列呼叫會修改陣列的方法,陣列本身就會被修改。 也就是說,它不會建立新的陣列,而是修改現有的陣列。

要建立陣列,請使用陣列常值表示語法([]),並在其中以逗號分隔指定陣列的元素。

[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)

說明

在這個練習中,你需要實作一些方法來操作程式語言的陣列。

1. 定義一個回傳空語言陣列的方法

定義LanguageList.list方法,它不接受任何引數,並回傳型別為Array(String)的空陣列。

LanguageList.list()
# => []

2. 定義一個將語言加入陣列的方法

定義LanguageList.add方法,它接受 2 個引數(一個_語言陣列_和一個_語言_的字串字面值)。 這個方法應該回傳把新語言加到陣列末端後的陣列。

language_list = LanguageList.list()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]

3. 定義一個從陣列移除語言的方法

定義LanguageList.remove方法,它接受 1 個引數(一個_語言陣列_)。 這個方法應該回傳移除最後一個項目後的陣列。 假設陣列至少會有一個項目。

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"]

4. 定義一個回傳陣列中第 n 個項目的方法

定義LanguageList.at函式,它接受 2 個引數(一個_語言陣列_和一個索引)。 這個方法應該回傳陣列中索引為 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"

5. 定義一個剖析語言字串的方法

定義LanguageList.parse方法,它接受 1 個引數(一個以逗號分隔的語言字串字面值)。 這個方法應該回傳一個語言陣列。

LanguageList.parse("Crystal, Ruby")
# => ["Crystal", "Ruby"]
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Crystal Exercism

準備好開始 語言清單 了嗎?

註冊 Exercism,透過 26 個概念142 個練習 和真人引導來學習並精通 Crystal,全部免費。