iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 22
0
Software Development

30天 Lua重拾筆記系列 第 22

【30天Lua重拾筆記21】基礎3: 再看pairs, ipairs

同步發表於個人網站

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與其現在的索引值,其反還下一個keyvalue。當indexnil時表示開始;反還的keynil表示結束。

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做了什麼,好改寫我們的pairsipairs

你可以用這種方式為userdata建立迭代器

my_pairs

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

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

上一篇
【30天Lua重拾筆記20】基礎3: 複合結構 - table
下一篇
【30天Lua重拾筆記22】中級議題: 全局表(_G)、環境表(_ENV)
系列文
30天 Lua重拾筆記36

尚未有邦友留言

立即登入留言