You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题分析

这段代码的核心问题:

  1. IndexOf(item)会返回第一个匹配项的索引,若列表存在非相邻的同名对象,会导致索引判断完全混乱。
  2. 遍历过程中依赖原列表的动态索引做判断,删除元素后原列表长度变化,容易出现跳过元素或逻辑错误。

正确解决方案

方案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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 06:00:28