关于List<T>.FindLast的应用小例子

实际游戏开发中,经常会有这种需求,比如玩家当前精通值1500,需要判断玩家当前的精通评价,如表。

按1500精通值,那么区间在1000~2000之间,玩家当前的正确评价是【略知一二】


首先最容易想到的循环遍历比对方式,没问题,但似乎有点僵硬,想着是不是可以改进一下

public SwordProficientConfig GetProficientLevel(int proficientValue)
{
    //如果精通值>=最后1条记录,直接返回最后一个记录
    if (proficientValue>=this.DataList[^1].SumProficientValue)
    {
        return this.DataList[^1];
    }
    
    for (int i = 0; i < this.DataList.Count; i++)
    {
        //如果不是最后1条,比对是否 >=当前记录 且 <下条记录
        if (proficientValue>=this.DataList[i].SumProficientValue && proficientValue<this.DataList[i+1].SumProficientValue)
        {
            return this.DataList[i];
        }
    }

    return this.DataList[0];
}

群里询问,大佬建议可以试试Find方法,于是自己去查了Find的用法,重新尝试。写完之后,emm.....用了,但是没完全用,判断思路上还是没有脱离第一种写法,而且显得更累赘,思维要跳出来。

public SwordProficientConfig GetProficientLevel2(int proficientValue)
{
    //如果精通值>=最后1条记录,直接返回最后一个记录
    if (proficientValue>=this.DataList[^1].SumProficientValue)
    {
        return this.DataList[^1];
    }

    //如果不是最后1条,比对是否 >=当前记录 且 <下条记录
    return this.DataList.Find(delegate(SwordProficientConfig config)
    {
        int nextIndex = this.DataList.IndexOf(config)+1;
        return proficientValue >= config.SumProficientValue && proficientValue < this.DataList[nextIndex].SumProficientValue;
    });
}

尝试改进,简洁了一些,但是有两个问题:

1、如果精通值>最大值,还是需要单独判断一次,不够简洁;

2、结果不正确,返回的是2000的记录,而不是1000的记录,因为1500不会<2000,那么2000就是首条匹配记录了;

public SwordProficientConfig GetProficientLevel3(int proficientValue)
{
    //如果精通值>=最后1条记录,直接返回最后一个记录
    if (proficientValue>=this.DataList[^1].SumProficientValue)
    {
        return this.DataList[^1];
    }
    
    //返回精通值>配置值的最后一条记录
    return this.DataList.Find(config => proficientValue < config.SumProficientValue);
}

最后把条件逆转一下,然后采用FindLast来返回最后一条符合的记录,完美,一行搞定!

public SwordProficientConfig GetProficientLevel3(int proficientValue)
{
    //返回精通值>配置值的最后一条记录
    return this.DataList.FindLast(config => proficientValue > config.SumProficientValue);
}
posted @ 2022-07-08 10:28  qianxun0975  阅读(124)  评论(0编辑  收藏  举报