Lua -- 重写pairs方法(让字典访问有序)

字典由于其独特的存储数据方式,我们访问一个字典可能会有不同的遍历顺序,当我们游戏中希望同一个字典,在不同手机上都有相同的访问顺序的时候,怎么办呢,我们可以重写字典的遍历方法pairs

local rawpairs = pairs
-------------------------------------------
-- 可以按指定顺序遍历的map迭代器
-- @param tbl 要迭代的表
-- @param func 比较函数
-- @example
-- for k,v in pairs(tbl,defaultComp) do print(k,v) end
function pairs(tbl, func)
    if func == nil then
        return rawpairs(tbl)
    end

    -- 为tbl创建一个对key排序的数组
    -- 自己实现插入排序,table.sort遇到nil时会失效
    local ary = {}
    local lastUsed = 0
    for key --[[, val--]] in rawpairs(tbl) do
        if (lastUsed == 0) then
            ary[1] = key
        else
            local done = false
            for j=1,lastUsed do  -- 进行插入排序
                if (func(key, ary[j]) == true) then
                    arrayInsert( ary, key, j )
                    done = true
                    break
                end
            end
            if (done == false) then
                ary[lastUsed + 1] = key
            end
        end
        lastUsed = lastUsed + 1
    end

    -- 定义并返回迭代器
    local i = 0
    local iter = function ()
        i = i + 1
        if ary[i] == nil then
            return nil
        else
            return ary[i], tbl[ary[i]]
        end
    end
    return iter
end

下面来实例使用一下新pairs

for k,v in pairs(table_name, function(op1,op2) return op1 > op2 end) do
    -- body...
end

写一个默认的比较函数供大家使用,如果不想写比较函数的话,可以使用下面的

--------------------------------
-- 通用比较器(Comparator)
-- @return 对比结果
function defaultComp( op1, op2 )
    local type1, type2 = type(op1), type(op2)
    local num1,  num2  = tonumber(op1), tonumber(op2)

    if ( num1 ~= nil) and (num2 ~= nil) then
        return  num1 < num2
    elseif type1 ~= type2 then
        return type1 < type2
    elseif type1 == "string"  then
        return op1 < op2
    elseif type1 == "boolean" then
        return op1
         -- 以上处理: number, string, boolean
    else -- 处理剩下的: function, table, thread, userdata
        return tostring(op1) < tostring(op2)  -- tostring后比较字符串
    end
end

使用方法

for k,v in pairs(table_name, defaultComp) do
    -- body...
end

当大家遇到lua给的方法不够使用的时候,大家可以自定义哦。

相关文章
相关标签/搜索