Lua_table.sort多条件(大量条件)自定义排序

#Lua_table.sort多条件(大量条件)自定义排序
之前简单写了(实际上大部分都是别人的链接)一些关于table.sortde的简单使用,采坑地点,常见使用等,这次就最近项目中的一个需求来记录一下。
##table.sort小记
1.排序的原理(快速排序)
2.排序顺序的依据(return a < b 看返回结果的判断 这个结果是小于)
3.排序的坑点(==的情况一定要返回false)
备注:如果需要自定义comp函数,copm(a,b) 如果需要a排在b的前边,
则 comp应该返回true。
注意,对于a等于b 情况,一定要返回false。
https://blog.csdn.net/wwlcsdn000/article/details/81711630
##需求概要
既然用到这个排序函数,我们的需求肯定是跟排序有关系的,常见的排序就不用说了。
常见排序举例:
1.单条件排序-- 哪个条件大的排在前边
2.多条件排序(存在优先级)
常见的2-3种条件判断A B C条件可用简单的三层判断解决
先看A,A不相等 ,A大的 满足则在前,不满足在后
先看A,A相等,再看B条件
B条件判断同上

我们来看一个多种条件并且不可按照是否逻辑在区分的条件排序情况(大量情况)
现在有一个排序规则是这样的,需要对物品进行一个按规则的排序。
物品有四大类,装备类型,材料类型,血瓶类型,技能书类型
先根据是否本职业可用排序,可用装备在上,不可用装备在下
再根据装备品质进行排序,品质高的在上,品质低的在下
最后根据装备类型排序,武器>胸甲>鞋子>头盔

材料,血瓶排在可用装备之后,先血瓶再材料,材料也根据品质排序

#需求分析
我们先来简单分析一下物品的排序规则(实际情况我已经做了删减,实际处理可能情况更多)
我现在的排序大种类情况是有11个大类别,每个类别下边可能还会有嵌套2-3个条件判断排序。
如下说思路,
针对一个具体的我们我们首先要分析它是什么种类的属于,
然后针对每个种类可能又需要有单独的排序规则(比如装备品质,等级)
当然规则适用可能又一定的前提条件(比如可穿戴的,不可穿戴无所谓了)

简单梳理下的基本的排序规则情况(从上到下)

本职业可用装备 装备等级 装备品质

血瓶

材料 按品质 高-低

不可用装备

##思路设计
这里我们的排序的规则是没有规律的,所以不能用简单的判断直接返回结果。
首先我们需要定义不同的bool变量去区分基本的是否两种情况(比如是否是装备,是否可穿戴,是否是材料等)
然后我采用了一个单独的自定义规则索引表
用每个索引代表每种情况
比如 1 ---- 可用装备 2------血瓶 3------- 材料 4------------不可用装备
针对每个种类的情况我们有需要单独进行处理

1.可用装备 我们根据装备品质先排序,然后根据装备品质(常规处理)
2.血瓶 无需特殊处理
3.材料 根据材料品质
4.不可用装备 无需特殊处理

##伪代码参考

由于显示等问题最终的结果可能是相反的请自行调整其中的判断关系。

local sort_index = {
    equip_yes = 1,
    blood = 2,
    material = 3,
    equip_no = 4,
}

local get_sort_index = function(item)
    local id = item.drop_data.item_id
    local item_index
    local ItemType = CommonItem.Item[id].Type

    --first do simple  blood and material
    if ItemType == const.TYPE_Blood then
        item_index = sort_index.blood
        return item_index
    elseif ItemType == const.TYPE_Material then
        item_index = sort_index.material
        return item_index
    end

    local playerType = HeroManager.player.vocation
    -- exception handling
    if not playerType then
        return -1
    end

    -- equipment
    local equiproleType
    if EquipItem.equipTemplate[id] then
        equiproleType = EquipItem.equipTemplate[id].vocation[1]
    end

    if equiproleType then
        if equiproleType == playerType then
            item_index = sort_index.equip_yes
        else
            item_index = sort_index.equip_no
        end
        return item_index
    end

    return -1
end


local equal_sort_index = function(sortA,sortB,A,B)

    if not sortA or not sortB then
        return false
    end

    if sortA ~= sortB then
        return false
    end

    local idA = A.id
    local idB = B.id

    if sortA == sort_index.equip_yes then

        local qualityA = CommonItem.Item[idA].Quality
        local qualityB = CommonItem.Item[idB].Quality

		local levelA = CommonItem.Item[idA].Level
        local levelB = CommonItem.Item[idB].Level
        if levelA ~= levelB then
            return levelA < levelB
        end

        if levelA == levelB then
            return qualityA > qualityB
        end

    elseif sortA == sort_index.material then
        local qualityA = CommonItem.Item[idA].Quality
        local qualityB = CommonItem.Item[idB].Quality

        if qualityA ~= qualityB then
            return qualityA < qualityB
        end

    else
        return false
    end

    return false

end

--comp way
local comp_pick = function(a,b)
    if a == nil or b == nil then
        return false
    end

    local idA = a.id
    local idB = b.id
    -- if same item
    if idA == idB then
        return false
    end

    local sortIndexA = get_sort_index(a)
    local sortIndexB = get_sort_index(b)

    if sortIndexA == sortIndexB then
        -- Sub case do
        local result
        result = equal_sort_index(sortIndexA,sortIndexB,a,b)
        return result
    else
        return sortIndexA > sortIndexB
    end

    return false
end

--use way 
table.sort(this.youtable,comp_pick)

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页