Lua table遍历

工作中,栽了一个“坑”,特此备录。

【1】遍历table1,每次结果可能都不同

-- 获取value
local table_1 = {id="101", name="wang", sage="18", addr="xian"}
for k, v in pairs(table_1) do
    print(k, v)
end

每次结果可能都不同

【2】遍历table2,每次结果相同

 1 local table_2 = {"101", "wang", "18", "xian"}
 2 
 3 print('len2 : ' .. (#table_2))
 4 
 5 local value_idx = {}
 6 for i = 1, #table_2 do
 7     print(i .. ' '.. table_2[i])
 8     table.insert(value_idx, table_2[i])
 9 end
10 print(table.concat(value_idx, ","))
11 
12 for k,v in ipairs(table_2) do
13     print(k, v)
14 end
15 
16 --[[
17 len2 : 4
18 1 101
19 2 wang
20 3 18
21 4 xian
22 101,wang,18,xian
23 1    101
24 2    wang
25 3    18
26 4    xian
27 --]]

每次结果相同

【3】table遍历的方法

经学习,总结一下table遍历的四种方法:

(3.1)利用迭代器pairs的方式

形式如下:

for key, value in pairs(tbtest) do      
    -- TODO  
end

示例如上第一节的实例,不再赘述。

特点:一定会遍历所有的元素,但并非按tbtest中key的排列顺序,而是根据tbtest中key的hash值排列的顺序来遍历的。

(3.2)利用迭代器ipairs的方式

形式如下:

for key, value in ipairs(tbtest) do
    -- TODO 
end

示例如上第二节的实例,另外,再如下:

 1 tbtest = {[1] = 100, [2] = 200, [3] = 300, [5] = 500} 
 2 
 3 for key, value in ipairs(tbtest) do
 4     print('key : ' .. key .. ' value : ' .. value)
 5 end
 6 
 7 --[[
 8 key : 1 value : 100
 9 key : 2 value : 200
10 key : 3 value : 300
11 --]]

特点:必须要求tbtest中的key为顺序的,且必须是从1开始,ipairs只会从1开始按连续的key顺序遍历到key不连续为止。

(3.3)下标索引方式

形式如下:

for i = 1, #(tbtest) do
    -- TODO  
end

示例如上第二节的实例,不再赘述。

特点:只能遍历当tbtest中存在key为1的场景,而且是严格按照key从1开始依次递增1的顺序来遍历,找不到下一个递增是1的key时候就结束遍历,无论后面是否是顺序的key

(3.4)自定义迭代器

形式如下:

function pairsByKeys(t)
    local a = {}  
    for n in pairs(t) do
        a[#a+1] = n  
    end
    table.sort(a)
    local i = 0  
    return function()  
        i = i + 1  
        return a[i], t[a[i]]  
    end  
end

for key, value in pairsByKeys(tbtest) do
    if destKey <= key then
        -- TODO
    end
end

应用场景:

网上有个实际的应用场景,感觉挺应景的。比如,学校按照班级排名顺序给学生发奖金,规则如下:

1.1 排名前4(1,2,3,4)的学生奖励500元

1.2 排名前8(5,6,7,8)的学生奖励300元

1.3 排名前12(9,10,11,12)的学生奖励200元

1.4 排名前16(13,14,15,16)的学生奖励100元

现在,准备给小王发奖金,小王排名第7名,理论应该发奖金是300元。

但是,对比方式(1)和方式(4)的遍历结果如下:

 1 tbtest = {[4] = 500, [8] = 300, [12] = 200, [16] = 100} 
 2 
 3 function pairsByKeys(t)  
 4     local a = {}  
 5     for n in pairs(t) do
 6         print('n : ' .. n)
 7         a[#a+1] = n  
 8     end
 9     table.sort(a)
10     local i = 0  
11     return function()  
12         i = i + 1  
13         return a[i], t[a[i]]  
14     end  
15 end
16 
17 print('-------------方式(3.1)-------------')
18 for k, v in pairs(tbtest) do
19     if 7 <= k then
20         print('pairs : ' .. k .. ' value : ' .. v)
21         break
22     end
23 end
24 
25 print('-------------方式(3.4)-------------')
26 for key, value in pairsByKeys(tbtest) do
27     print('key : ' .. key .. ' value : ' .. value)
28     if 7 <= key then
29         print('pairsByKeys : ' .. key .. ' value : ' .. value)
30         return
31     end
32 end
33 
34 --[[
35 -------------方式(3.1)-------------
36 pairs : 12 value : 200
37 -------------方式(3.4)-------------
38 n : 4
39 n : 12
40 n : 8
41 n : 16
42 key : 4 value : 500
43 key : 8 value : 300
44 pairsByKeys : 8 value : 300
45 --]]

原因分析:因为方式(1)是按照key值的hash值进行遍历的,而不是按照key值的大小顺序进行遍历。

而方式(4)对方式(1)做了改进,先对所有的key值进行了排序,然后再依次遍历,满足预期的效果。

综上所述:方式(4)是对方式(1)的不足进行了弥补,具体应用过程中,根据实际情况,择优选择遍历方法。

 

Good Good Study, Day  Day  Up.

顺序 选择 循环 总结

 

转载于:https://www.cnblogs.com/Braveliu/p/10750574.html

<think>好的,我现在需要回答用户关于如何遍历Lua table的问题。首先,我得回忆一下Luatable的基本结构,以及常用的遍历方法。Luatable有数组部分和哈希表部分,所以遍历方式可能不同。 用户可能想知道如何遍历数组部分和键值对。我记得常用的有ipairs和pairs函数。ipairs用于顺序遍历数组部分,而pairs可以遍历所有元素。不过需要确认这两者的具体区别,比如ipairs是否在遇到nil时停止,而pairs是否包括非数字键。 接下来,我应该举例说明。比如,数组遍历可以用ipairs,而哈希表用pairs。同时,用户可能还想知道如何按特定顺序遍历,比如按键排序后的顺序。这时候可能需要先用table.keys获取所有键,然后排序,再遍历。 需要注意错误的使用方法,比如用pairs遍历数组,虽然可行,但顺序可能不保证。或者用ipairs遍历混合table,可能漏掉非数字键的元素。另外,用户可能关心性能问题,比如ipairs和pairs的效率差异,但一般来说在Lua中这两者效率接近,但最好根据使用场景选择。 还要提到通用遍历方法,比如使用next函数手动控制迭代,不过这种情况较少见。用户可能需要基本用法,所以重点放在ipairs和pairs的区别和示例上。 最后,总结不同情况下的推荐方法,确保用户能根据需求选择合适的遍历方式。可能还要提醒,Lua的数组索引默认从1开始,这点在遍历时需要注意,避免出现off-by-one错误。</think>在 Lua 中,遍历 table 主要有以下几种方式,我们通过具体示例逐步说明: ### 1. 遍历数组部分(顺序索引) 使用 `ipairs` 函数遍历连续数字索引的数组元素,遇到 `nil` 会停止: ```lua local arr = {"apple", "banana", "cherry"} for i, v in ipairs(arr) do print(i, v) -- 输出:1 apple → 2 banana → 3 cherry end ``` ### 2. 遍历所有元素(键值对) 使用 `pairs` 函数遍历 table 的所有键值对(包括非数字键): ```lua local dict = { name = "Alice", age = 30, [5] = "特殊键", "数组元素" } for k, v in pairs(dict) do print(k, v) -- 可能输出:1 数组元素 → age 30 → name Alice → 5 特殊键 end ``` ### 3. 按特定顺序遍历 如果需要有序遍历,需先提取键并排序: ```lua local t = {z=3, a=1, b=2} local keys = {} -- 提取所有键 for k in pairs(t) do table.insert(keys, k) end -- 排序键 table.sort(keys) -- 按排序后的键遍历 for _, k in ipairs(keys) do print(k, t[k]) -- 输出:a 1 → b 2 → z 3 end ``` ### 4. 遍历注意事项 - `ipairs` 和 `pairs` 的区别: - `ipairs`:遍历连续数字索引(1,2,3...),遇到 `nil` 停止 - `pairs`:遍历所有键值对(顺序不保证) - 混合类型 table遍历: ```lua local mixed = { "数组元素1", [3] = "数字键3", key = "字符串键", "数组元素2" } -- ipairs 遍历(只输出索引1和2) for i,v in ipairs(mixed) do print(i,v) -- 输出:1 数组元素1 → 2 数组元素2 end -- pairs 遍历所有元素 for k,v in pairs(mixed) do print(k,v) -- 输出可能包含:1、2、3、"key" end ``` ### 5. 性能优化技巧 - 数组优先:需要高效遍历时,优先使用数字索引数组 - 避免修改:遍历过程中不要修改表结构(增删元素) - 缓存长度:对于大数组可先保存长度 `local n = #t` 选择遍历方式: - 纯数组 → 用 `ipairs` - 需要所有元素 → 用 `pairs` - 需要有序遍历 → 先提取键并排序 可以通过以下命令验证遍历效果: ```bash lua -e 't = {a=1,b=2}; for k,v in pairs(t) do print(k,v) end' ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值