如何按照表格的确切顺序迭代表格?

如果我尝试输出此表格,则它们会按错误顺序循环:

local letters   =   {DIN1="hi", AIN1= "my", AIN2 ="name", DIN2="is"}

for name, value in pairs(letters) do
    print(name,value)
end

期望的输出:

DIN1   hi
AIN1   my
AIN2    name
DIN2   is

输出:

AIN1    my
DIN2    is
DIN1    hi
AIN2    name

如何编写代码,使for循环按照表的实际顺序运行?(按照定义的顺序)

编辑:我不需要按字母顺序排列,而是按表的定义顺序排列。

编辑:我需要打印键和值。 在答案“以与编写相同顺序的Lua成对出现”中,只会打印索引号和值。

点赞
用户4684797
用户4684797

我用以下代码绕开了此问题,但这个解决方案当然不是完美的。

local letters = {"DIN1=hi", "DIN2 = my", "AIN1 = name", "LE = is" }
local pattern = "(%S+)%s*=%s*(%S+)"

for _, n in pairs(letters) do
    key, value = n:match(pattern)
    print(key, value)
end

输出结果:

DIN1    hi
DIN2    my
AIN1    name
LE      is
2015-06-22 09:09:56
用户3125367
用户3125367

您可以使用表的整数部分来按顺序存储键:

function add(t, k, v, ...)
    if k ~= nil then
        t[k] = v
        t[#t+1] = k
        return add(t, ...)
    end
    return t
end

t = add({ }, "A", "hi", "B", "my", "C", "name", "D", "is")

for i,k in ipairs(t) do
    local v = t[k]
    print(k, v)
end

当然,这假定整数键除了 add 之外没有被其他东西使用。

insert(t, k, v)remove(t, k) 留给读者练习。

编辑: add 函数中的省略号(点)允许传递尽可能多的参数来一次性设置多个键值对。如果没有省略号,我们只能在每次调用时设置一个 pair,像这样 add(t, "A", "hi")。函数定义 add(t, k, v, ...) 将前三个参数分配给 t, k, v,并保持其他参数不变。然后 add 处理第一对(t[k]=v)并将剩下的 ... 参数递归地处理。

          t   k    v    ...
level 1: (t, "A", "hi", "B", "my", "C", "name", "D", "is")
level 2: (t,         <- "B", "my", "C", "name", "D", "is")
level 3: (t,                    <- "C", "name", "D", "is")
level 4: (t,                                 <- "D", "is")
level 5: (t,                                          <- )

在第 5 级,kvnil,因为参数列表太短,递归停止。

2015-06-22 10:39:03
用户577603
用户577603

Lua-users 的 Wiki 上有一个页面来解决这个问题。

引用该页面上的代码:

--[[
Ordered table iterator, allow to iterate on the natural order of the keys of a
table.

Example:
]]

function __genOrderedIndex( t )
    local orderedIndex = {}
    for key in pairs(t) do
        table.insert( orderedIndex, key )
    end
    table.sort( orderedIndex )
    return orderedIndex
end

function orderedNext(t, state)
    -- Equivalent of the next function, but returns the keys in the alphabetic
    -- order. We use a temporary ordered key table that is stored in the
    -- table being iterated.

    key = nil
    --print("orderedNext: state = "..tostring(state) )
    if state == nil then
        -- the first time, generate the index
        t.__orderedIndex = __genOrderedIndex( t )
        key = t.__orderedIndex[1]
    else
        -- fetch the next value
        for i = 1,table.getn(t.__orderedIndex) do
            if t.__orderedIndex[i] == state then
                key = t.__orderedIndex[i+1]
            end
        end
    end

    if key then
        return key, t[key]
    end

    -- no more value to return, cleanup
    t.__orderedIndex = nil
    return
end

function orderedPairs(t)
    -- Equivalent of the pairs() function on tables. Allows to iterate
    -- in order
    return orderedNext, t, nil
end

这里的“键的自然顺序”指的是从最小的键(就好像通过a<b样式的比较来确定)开始,这不一定是您在填充表时首先写的键(后者更为复杂,也更不合理)。

然后您可以直接使用orderedPairs函数来替换pairs:

local letters   =   {A="hi", B= "my", C ="name", D="is"}

for name, value in orderedPairs(letters) do
    print(name,value)
end
2015-06-22 11:02:42
用户107090
用户107090

为了说明,没有确切的顺序。

Lua 中的表是一组键值对。表定义只是为了一次性设置多个键值对的简写。只有当有重复的键时,键值对被定义的顺序才有关系:最后一个相同键的键值对是留在表中的。

2015-06-22 14:22:51