Lua:ipairs/pairs

来源:互联网 发布:php怎么找工作 编辑:程序博客网 时间:2024/06/06 00:17

Lua:ipairs/pairs

Lua中有两个很类似的函数:ipairs以及pairs。

实验环境:

[test1280@localhost 20170531]$ uname -aLinux localhost.localdomain 2.6.18-371.el5 #1 SMP Thu Sep 5 21:21:44 EDT 2013 x86_64 x86_64 x86_64 GNU/Linux[test1280@localhost 20170531]$ lua -vLua 5.3.4  Copyright (C) 1994-2017 Lua.org, PUC-Rio

pairs(t)

sample 1:

test.lua:

t = {"a", "b", "c", "d", "e", "f"}for k, v in ipairs(t) do    print("key is " .. k)    print("value is " .. v)end
[test1280@localhost 20170531]$ lua test.lua key is 1value is akey is 2value is bkey is 3value is ckey is 4value is dkey is 5value is ekey is 6value is f

上面的输出可以证明:

1.在Lua中ipairs是从下标1开始的,并不是从0开始;

2.就如同我们例子中的变量名,k以及v,就是key以及value,每次都会返回两个值赋给k以及v,然后可以在loop-body部分使用。

sample 2:

test.lua:

t = {    "a", "b", "c";    one = "d", two = "e", three = "f";}for k, v in ipairs(t) do    print("key is " .. k)    print("value is " .. v)end
[test1280@localhost 20170531]$ lua test.luakey is 1value is akey is 2value is bkey is 3value is c

前三个还是正常迭代的,第四个出问题了。

因为ipairs总是从1开始进行迭代:

如果t[n]的值不是nil,那么就可以进入循环==》

if (t[1] ~= nil) then    do loop-bodyif (t[2] ~= nil) then    do loop-bodyif (t[3] ~= nil) then    do loop-body...

当发现t[n]值是nil时则直接退出循环。

思考下面的代码输出什么:

sample 3:

test.lua:

t = {    zero = "this is zero",    "a", "b", "c";    one = "d", two = "e", three = "f";}for k, v in ipairs(t) do    print("key is " .. k)    print("value is " .. v)end
[test1280@localhost 20170531]$ lua test.lua key is 1value is akey is 2value is bkey is 3value is c

千万不要以为将一个key-value放置在table靠前处就可以阻挡ipairs…

记住,无论table是啥,ipairs总是尝试从1开始索引,判断是否是nil,不是nil则进入loop-body,是nil则退出,依次类推。

sample 4:

test.lua:

t = {    zero = "this is zero",    one = "d", two = "e", three = "f";}t[1] = "a"t[2] = "b"t[3] = "c"for k, v in ipairs(t) do    print("key is " .. k)    print("value is " .. v)end

其实这里的修改是与sample 3等价的,输出如下:

[test1280@localhost 20170531]$ lua test.lua key is 1value is akey is 2value is bkey is 3value is c

假若:

sample 5:

test.lua:

t = {    zero = "this is zero",    one = "d", two = "e", three = "f";}t[1] = nilt[2] = "b"t[3] = "c"for k, v in ipairs(t) do    print("key is " .. k)    print("value is " .. v)end

输出将会是什么?

Answer is:啥也不输出。

sample 6:

test.lua:

t = {    zero = "this is zero",    one = "d", two = "e", three = "f";}t[1] = "a"t[2] = nilt[3] = "c"for k, v in ipairs(t) do    print("key is " .. k)    print("value is " .. v)end

输出是啥?

[test1280@localhost 20170531]$ lua test.lua key is 1value is a

回想我们刚刚的过程:

先判断t[1]是不是nil,发现不是,那么就进入loop-body;
在判断t[2]是不是nil,发现是,那么就退出…

由以上的ipairs引出一个问题,如何迭代一个既有数组类型,又有记录风格(就是key-value风格)的table呢?

下面就轮到pairs出场了。


pairs(t)

sample 7:

test.lua:

t = {    zero = "this is zero",    one = "d", two = "e", three = "f";}t[1] = "a"t[2] = nilt[3] = "c"for k, v in pairs(t) do    print("key is " .. k)    print("value is " .. v)end
[test1280@localhost 20170531]$ lua test.lua key is 1value is akey is onevalue is dkey is 3value is ckey is threevalue is fkey is twovalue is ekey is zerovalue is this is zero

sample 7对比sample 6只是将ipairs改成了pairs,结果却大不相同。

从输出中看到一下三点:

pairs可以遍历tabe中所有的元素,无论是key-value或者是数组类型;

pairs对元素(key)的遍历是无序的,这一点需要注意,因为这里的遍历是与key的哈希值有关,有机会我再看看源码^_^;

pairs没有对t[2]输出key is 2,为什么呢?因为在Lua中,一个值是nil,本身代表这个值压根没有定义过…

总结:

ipairs和pairs都可以对table进行遍历,但是:

ipairs总是对数组类型按序进行遍历,但也仅仅对数组类型的元素遍历了,而对key-value类型不闻不问;

pairs相对ipairs可以对所有的table元素进行遍历,包括key-value类型,但是其遍历不是按照某些特定的顺序(比如key字典顺序等等),而是与key的Hash值有关,表现出来的就是无序的遍历,这一点需要注意。

Tips:

对ipairs以及pairs可以认为,加了“i”的是对数组进行遍历,整数么,哈哈。

特别需要注意的是,在迭代时对table的修改会不会影响迭代本身呢?(参见lua_next)==》