按优先级移除列表元素:现有实现的优化方案咨询
优化有序列表优先级过滤的C#实现方案
需求背景
给定一个按gold>silver>bronze优先级排序的有序字符串列表,需按以下规则移除低优先级元素:
- 若列表包含"Best gold",移除所有"Best silver"和"Best bronze";
- 若列表不含"Best gold"但含"Best silver",移除"Best bronze";
- 若前两者都不存在,保留所有"Best bronze"。
原实现的效率问题
当前提供的代码虽然能正常运行,但存在明显性能短板:
- 多次全量遍历:两次
Contains+两次RemoveAll,最多会遍历列表4次,大列表场景下损耗明显; - 冗余类型转换:每次判断都重复强制转换
x为string,完全没必要。
优化方案(利用有序特性)
因为列表是按优先级排序的,所有"Best gold"集中在最前端,其次是"Best silver",最后是"Best bronze"。我们可以利用这个特性,通过定位分界点批量移除元素,大幅减少遍历次数:
// 先检查是否存在Best gold int firstGoldIndex = sortedArr.FindIndex(item => item == "Best gold"); if (firstGoldIndex != -1) { // 找到第一个非Best gold的元素位置,批量移除后面所有元素 int firstNonGold = sortedArr.FindIndex(firstGoldIndex, item => item != "Best gold"); if (firstNonGold != -1) sortedArr.RemoveRange(firstNonGold, sortedArr.Count - firstNonGold); } else { // 检查是否存在Best silver int firstSilverIndex = sortedArr.FindIndex(item => item == "Best silver"); if (firstSilverIndex != -1) { // 找到第一个Best bronze的位置,批量移除后面所有元素 int firstBronze = sortedArr.FindIndex(item => item == "Best bronze"); if (firstBronze != -1) sortedArr.RemoveRange(firstBronze, sortedArr.Count - firstBronze); } // 前两者都不存在时,不做任何操作,保留所有元素 }
优化优势
- 最少遍历次数:最多遍历列表2次(找目标元素+找分界点),远少于原实现的多次全量遍历;
- 批量操作高效:
RemoveRange是一次性批量移除元素,比RemoveAll逐个判断移除的效率更高; - 无冗余转换:直接使用列表元素的
string类型判断(若列表不是List<string>,可提前转换一次)。
另一种简洁实现(LINQ方式)
如果更倾向于简洁的代码风格,也可以用LINQ一次性过滤,适合中小规模列表:
bool hasGold = sortedArr.Contains("Best gold"); bool hasSilver = !hasGold && sortedArr.Contains("Best silver"); sortedArr = sortedArr.Where(item => hasGold ? item == "Best gold" : hasSilver ? item != "Best bronze" : true).ToList();
这种实现代码更简洁,但本质是全量遍历一次,适合对可读性要求高于极致性能的场景。
内容的提问来源于stack exchange,提问作者gouravm
相关产品推荐
相关产品推荐

