Lua:ipairs/pairs

Lua:ipairs/pairs

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

实验环境:

[test1280@localhost 20170531]$ uname -a
Linux 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 -v
Lua 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 1
value is a
key is 2
value is b
key is 3
value is c
key is 4
value is d
key is 5
value is e
key is 6
value 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.lua
key is 1
value is a
key is 2
value is b
key is 3
value is c

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

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

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

if (t[1] ~= nil) then
    do loop-body
if (t[2] ~= nil) then
    do loop-body
if (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 1
value is a
key is 2
value is b
key is 3
value 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 1
value is a
key is 2
value is b
key is 3
value is c

假若:

sample 5:

test.lua:

t = {
    zero = "this is zero",
    one = "d", two = "e", three = "f";
}

t[1] = nil
t[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] = nil
t[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 1
value 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] = nil
t[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 1
value is a
key is one
value is d
key is 3
value is c
key is three
value is f
key is two
value is e
key is zero
value 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)==》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值