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.

順序 選擇 循環 總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM