关于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);
}