iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 20
0
Software Development

30天 Lua重拾筆記系列 第 20

【30天Lua重拾筆記19】基礎3: 陣列從1開始

同步發表於個人網站

建立陣列

關於陣列,其實也已經看過了。不過其實陣列還有兩個祕密,一個今天會揭露,另一個等等明天。

要建立一個陣列很簡單,很像C語言,只是把中括號[]改成大括號{},像是:

programming_language = {
  "C",
  "C#",
  "C++",
  "Java",
  "Swift",
  "Python",
  "Haskell",
}

陣列取值

陣列從1開始

與C語言一樣,使用下標運算取陣列之中的值, 要注意的是,Lua陣列從1開始

print(programming_language[1]) -- => Output: "C"

陣列長度

可以使用長度運算#,取得陣列長度:

print(#programming_language) -- => Output: 7

迭代陣列

知道陣列取值方式,也知道陣列長度後,就可以來迭代陣列:

一般for迴圈方法

for i=1, #programming_language, 1 do
  print(i, #programming_language[i], programming_language[i])
end

看我小巧思,每個值的長度,正好與其對應的索引值相同。

for-in + ipairs() 方法

可以寫的更簡單點:

for i in ipairs(programming_language) do
  print(i, #programming_language[i], programming_language[i])
end

基礎2: 控制-for迴圈看過,可以直接在for綁定其值:

for i, lang in ipairs(programming_language) do
  print(i, #lang, lang)
end

這樣好閱讀多了?

增加陣列長度

總是只在尾端插入元素

除了重新指定值以外,可以賦予值於陣列長度外,以做到增加陣列長度的需求:

print(#programming_language) --> Output: 7
programming_language[#programming_language + 1] = 'ECMAScript'
print(#programming_language) --> Output: 8

也可以使用table.insert()

print(#programming_language) --> Output: 8
table.insert(programming_language, "Shell Script")
print(#programming_language) --> Output: 9

刪除陣列

強烈建議只總是刪除尾端元素!

陣列刪除,只需要將其值設為nil即可。

print(#programming_language) --> Output: 9
programming_language[#programming_language] = nil
print(#programming_language) --> Output: 8

!!強烈建議只總是刪除尾端元素!!

雖然可以刪除任意,但可能發生意想不到的結果:

print(#programming_language) --> Output: 8
programming_language[2] = nil -- delete "C#"
print(#programming_language) --> Output: 8  ---- What's!?

上面執行後長度並沒有改變,而且還引發一個可能想不到的行為:

ipairs()迭代不正常了?

for i, lang in ipairs(programming_language) do
  print(i, #lang, lang)
end

1 1 C
-- 其他值呢?

ipairs()的寫法可能不能用了,只能使用一般for迴圈寫法:

for i=1, #programming_language, 1 do
  print(i, programming_language[i])
end

1 C
2 nil
3 C++
4 Java
5 Swift
6 Python
7 Haskell
8 ECMAScript

注意到:第二個值變成nil,長度依然為8

作業

陣列實際上可以在初始值,都標上每個索引值,如:

arr = {
  [1] = 1,
  [2] = 1,
  [3] = 1,
  [4] = 1,
  [5] = 1,
}

print(#arr) --> 5

作業

試問下列得到的arr長度為多少?

arr = {
  [0] = 1,
  [1] = 1,
  [2] = 1,
  [3] = 1,
  [4] = 1,
  [5] = 1,
}

print(#arr) --> ?

答案

  1. 5

陣列長度從索引1開始計算。

其他應該注意事項

總是使用正常的陣列初始化

儘管Lua允許明確標示索引值,但其行為可能會與不標注的不同:

arr1 = {1,nil,3,4,5}
arr2 = {1,2,nil,4,5}

print(#arr1) --> 5
print(#arr2) --> 5

上面兩者長度都正常為5。下面雖然看起來相同,卻可能有不同長度:

arr1 = {
  [1] = 1,
  [2] = nil,
  [3] = 3,
  [4] = 4,
  [5] = 5
}

arr2 = {
  [1] = 1,
  [2] = 2,
  [3] = nil,
  [4] = 4,
  [5] = 5
}

print(#arr1) --> 1
print(#arr2) --> 5

總是只在尾端插入元素

或許你明白不從尾端刪除元素的意義。但是很容易搞混不從尾端加入函數的行為。

arr = {1,nil,3,4,5}

print(#arr) --> 5

arr[7] = 7
print(#arr) --> 7 -- What's !? 直接變成7

arr[9] = 9
print(#arr) --> 7 -- What's !? 長度沒有增加

OS: 執行結果不一樣?別問我,我也不知道為什麼
總之,別這樣做!


上一篇
【30天Lua重拾筆記29】物件導向 之 HoloLive 炎上! 桐生可可&赤井心 禁足三周
下一篇
【30天Lua重拾筆記20】基礎3: 複合結構 - table
系列文
30天 Lua重拾筆記36

尚未有邦友留言

立即登入留言