Lua Table pairs输出顺序问题 (版本差别 解决数字索引间断并兼容字符串索引)

问题标签:测试

  Lua Table 迭代器;Lua Table 输出顺序; Lua Table 顺序输出;Lua Table 数字索引 字符串索引;Lua Table pairs;lua

问题背景:spa

  使用pairs输出table时,其输出顺序与一般认知不相符.code

  例如使用pairs输出以下tableblog

T = {
    [1] = "1",
    [2] = "1",
    [3] = "1",
    [4] = "1",
    [5] = "1",
    
    [10] = "1",
    [20] = "1",
    [30] = "1",
    [40] = "1",
    [50] = "1",
    
    [11] = "1",
    [12] = "1",
    [13] = "1",
    q = "1",
    [14] = "1",
    w = "1",
    [15] = "1",
    e = "1",
    r = "1",
    t = "1",
    y = "1",
}

for k,v in pairs(T) do
    print(k)
end

咱们一般认为:输出结果会是先顺序输出12345,再乱序输出其它索引

可是恰巧 在lua 5.1.5 都是乱序字符串

 

 

经测试在lua 5.1.5,若是想与一般认为相符,那么就不能显示指定索引值,只能隐式指定索引值,就是把上述table改为这样:string

 

T = {
    "1",
    "1",
    "1",
    "1",
    "1",
    
    [10] = "1",
    [20] = "1",
    [30] = "1",
    [40] = "1",
    [50] = "1",
    
    [11] = "1",
    [12] = "1",
    [13] = "1",
    q = "1",
    [14] = "1",
    w = "1",
    [15] = "1",
    e = "1",
    r = "1",
    t = "1",
    y = "1",
}

 

可是这种解决办法,显然让人没法接受,让人窒息.因此今天研究了一下解决办法io

 

目标:table

  使用迭代器输出Table时,首先顺序输出数字索引(容许数字索引间断),最后输出字符串索引

问题解决:

  灵感来源于<Programming In Lua>中的代码:

 

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(表) do      
     
end 

 

  可是这个还差点意思,当table中包含字符串索引时,会报错.咱们指望能和pairs同样兼容字符串索引.咱们强化一下,以下:

function spairs(t)
    local num_key_table = {}
    local string_key_table = {}
    
    for k,v in pairs(t) do
        if type(k) == "number" then
            num_key_table[#num_key_table + 1] = k
        else
            string_key_table[k] = v
        end
    end
    
    table.sort(num_key_table)
    
    local i = 0
    
    return function()
        if  i < #num_key_table then
            i = i + 1
            return num_key_table[i], t[num_key_table[i]]
        else
            for k,v in pairs(string_key_table) do
                string_key_table[k] = nil
                return k,v
            end
        end
    end
end

for k,v in spairs(T) do
    print(k)
end

对比:

还有改进的地方,欢迎指导

相关文章
相关标签/搜索