C#中如何移除List中的相邻重复元素?
移除List中相邻重复的NewsModel项
我有一个NewsModel类型的List,需要仅移除其中的相邻重复项(仅删除和前一个元素Name相同的项,保留每组相邻重复的第一个)。
示例列表
var data = new List<NewsModel> { new NewsModel { ID = 1, Name = "AAA" }, new NewsModel { ID = 2, Name = "AAA" }, new NewsModel { ID = 3, Name = "BBB" }, new NewsModel { ID = 4, Name = "CCC" }, new NewsModel { ID = 5, Name = "CCC" }, new NewsModel { ID = 6, Name = "AAA" }, new NewsModel { ID = 7, Name = "DDD" }, new NewsModel { ID = 8, Name = "DDD" }, new NewsModel { ID = 9, Name = "CCC" } };
预期结果
var data = new List<NewsModel> { new NewsModel { ID = 1, Name = "AAA" }, new NewsModel { ID = 2, Name = "BBB" }, new NewsModel { ID = 3, Name = "CCC" }, new NewsModel { ID = 4, Name = "AAA" }, new NewsModel { ID = 5, Name = "DDD" }, new NewsModel { ID = 6, Name = "CCC" } };
我尝试的代码(未得到预期结果)
foreach (var item in NewsModel.ToList()) { if (NewsModel.Count() >= NewsModel.IndexOf(item) + 1) { _nextItem = NewsModel[NewsModel.IndexOf(item) + 1]; if (item.Name == _nextItem.Name) { NewsModel.Remove(item); } } }
问题分析
这段代码的核心问题:
IndexOf(item)会返回第一个匹配项的索引,若列表存在非相邻的同名对象,会导致索引判断完全混乱。- 遍历过程中依赖原列表的动态索引做判断,删除元素后原列表长度变化,容易出现跳过元素或逻辑错误。
正确解决方案
方案1:构建新列表(直观可靠)
直接遍历原列表,仅添加和前一个保留元素Name不同的项:
var filteredList = new List<NewsModel>(); if (data.Count == 0) return filteredList; filteredList.Add(data[0]); for (int i = 1; i < data.Count; i++) { if (data[i].Name != filteredList.Last().Name) { filteredList.Add(data[i]); } }
方案2:自定义LINQ扩展方法(简洁写法)
封装通用的相邻去重扩展方法,复用性更强:
public static IEnumerable<T> RemoveAdjacentDuplicates<T>(this IEnumerable<T> source, Func<T, T, bool> areEqual) { using var enumerator = source.GetEnumerator(); if (!enumerator.MoveNext()) yield break; var previous = enumerator.Current; yield return previous; while (enumerator.MoveNext()) { var current = enumerator.Current; if (!areEqual(previous, current)) { yield return current; previous = current; } } } // 使用方式 var filteredList = data.RemoveAdjacentDuplicates((x, y) => x.Name == y.Name).ToList();
方案3:原地修改原列表(保留原引用)
从后往前遍历删除,避免索引偏移问题:
for (int i = data.Count - 1; i > 0; i--) { if (data[i].Name == data[i - 1].Name) { data.RemoveAt(i); } }
内容的提问来源于stack exchange,提问作者TechGuy
相关产品推荐
相关产品推荐

