在 Lua 中,对 table 进行排序一般使用 Lua 自带的排序函数:

table.sort(list[, comp])

list 为需要排序的目标 table,可选参数 comp 为排序的比较函数!

如果不提供比较函数 comp,默认将使用标准 Lua 操作符 "<" 进行升序排序;如果提供了比较函数 comp,就相当于用提供的比较函数 comp 重载了 "<" 操作符!

下面举例说明一下 table.sort 的用法以及一些注意点:

1、table.sort 这个排序算法并不稳定,即当两个元素次序相等时,它们在排序后的相对位置可能会改变!

local tbl = {
    {id = 1, num = 88, level = 30},
    {id = 2, num = 66, level = 10},
    {id = 3, num = 66, level = 90},
    {id = 4, num = 99, level = 20},
    {id = 5, num = 66, level = 90}
}

table.sort(tbl, function(a, b)
    -- 按num降序排序
    return a.num > b.num
end)

for _, v in pairs(tbl) do
    print(string.format("id = %d, num = %d, level = %d", v.id, v.num, v.level))
end

-- id = 4, num = 99, level = 20
-- id = 1, num = 88, level = 30
-- id = 3, num = 66, level = 90
-- id = 2, num = 66, level = 10
-- id = 5, num = 66, level = 90

2、要求需要排序的目标 table 必须是从 1 到 n 连续的,即中间不能有 nil,否则会报错!

local tbl = {
    {id = 1, num = 88, level = 30},
    {id = 2, num = 66, level = 10},
    nil,
    {id = 3, num = 66, level = 90},
    {id = 4, num = 99, level = 20},
    {id = 5, num = 66, level = 90}
}

table.sort(tbl, function(a, b)
    -- 报错:table必须是从1到n连续的,即中间不能有nil,否则会报错
    return a.num > b.num
end)

for _, v in pairs(tbl) do
    print(string.format("id = %d, num = %d, level = %d", v.id, v.num, v.level))
end

3、当比较的两个元素相等的时候,比较函数一定要返回 false,返回 true 会报错!

local tbl = {
    {id = 1, num = 88, level = 30},
    {id = 2, num = 66, level = 10},
    {id = 3, num = 66, level = 90},
    {id = 4, num = 99, level = 20},
    {id = 5, num = 66, level = 90}
}

table.sort(tbl, function(a, b)
    if a.num >= b.num then
        -- 报错:当两个数相等的时候,比较函数一定要返回false,返回true会报错
        return true
    else
        return false
    end
    -- return a.num > b.num
end)

for _, v in pairs(tbl) do
    print(string.format("id = %d, num = %d, level = %d", v.id, v.num, v.level))
end

4、table.sort 的正确使用方式:

local tbl = {
    {id = 1, num = 88, level = 30},
    {id = 2, num = 66, level = 10},
    {id = 3, num = 66, level = 90},
    {id = 4, num = 99, level = 20},
    {id = 5, num = 66, level = 90}
}

table.sort(tbl, function(a, b)
    if a.num > b.num then
        -- 按num降序
        return true
    elseif a.num == b.num then
        -- 如果num相等,按level升序
        if a.level < b.level then
            return true
        elseif a.level == b.level then
            -- 如果level相等,按id降序
            return a.id > b.id
        end
    end
    return false
end)

for _, v in pairs(tbl) do
    print(string.format("id = %d, num = %d, level = %d", v.id, v.num, v.level))
end

-- id = 4, num = 99, level = 20
-- id = 1, num = 88, level = 30
-- id = 2, num = 66, level = 10
-- id = 5, num = 66, level = 90
-- id = 3, num = 66, level = 90
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐