同步發表於個人網站
ipairs()
的行為iparis會嘗試從索引1開始迭代表(陣列),直到其值為nil
。所以很像是:
arr = {1,2,3,4,5}
function my_ipairs(t --[[table]])
local i = 1
while t[i] ~= nil do
print(i, t[i])
i = i + 1
end
end
my_ipairs(arr)
1 1
2 2
3 3
4 4
5 5
也因此其如果有斷值,會在一半中止:
arr = {1,2,nil, 4, 5}
my_ipairs(arr)
1 1
2 2
pairs()
和next()
pairs()
更像直接使用了next()
。
next(table[, index])
接受一個table
與其現在的索引值,其反還下一個key
和value
。當index
是nil
時表示開始;反還的key
是nil
表示結束。
function my_pairs(t --[[table]])
local key, value = next(t)
while key do
print(key, value)
key, value = next(t, key)
end
end
arr = {1,2,nil, 4, 5}
my_pairs(arr)
1 1
2 2
4 4
5 5
※ Note: nil
不是合法的value
值,會被忽略。
pairs()
和ipairs()
的反還值pairs()
和ipairs()
的都反還三個值:一個迭代函數,類似next
、一個table
、一個當前的index
。將後兩者放入第一個函數,可以得到下一個的key
/value
。
所以我們可以改寫出自己的for-in
:
function for_in(f, -- first funciton
t, -- table
i --[[index]])
local key, value = f(t,i)
while key do
print(key, value)
key, value = f(t, key)
end
end
arr = {1,2,nil, 4, 5}
f, t, i = pairs(arr)
for_in(f,t,i)
print("----------")
f, t, i = ipairs(arr)
for_in(f,t,i)
現在,可以猜到for-in
做了什麼,好改寫我們的pairs
和ipairs
。
你可以用這種方式為
userdata
建立迭代器
my_pairs
很簡單,因為我們不用改寫next()
function my_pairs(t --[[table]])
return next, t, nil
end
arr = {1,2,nil, 4, 5}
for k, v in my_pairs(arr) do
print(k, v)
end
my_ipairs
需要一個內部的_next
,去確定下一個值存不存在。 其初始的index為0。
function my_pairs(t --[[table]])
local _next = function(t, i)
if t[i+1] then
return i+1, t[i+1]
end
end
return _next, t, 0
end
arr = {1,2,nil, 4, 5}
for i, v in my_pairs(arr) do
print(i, v)
end