如何使用Linq删除所有唯一对象

本文关键字:唯一 对象 删除 何使用 Linq | 更新日期: 2023-09-27 18:27:16

比方说,我有这样的LinkedList<T1>

{ A, B, C, D, E, F, G, H, I, J }

在此列表中:

B.param == C.param == F.param == p1G.param == I.param == p2,所以我必须获得下一个:

{ B, C, F, G, I }

如何使用Linq删除所有唯一对象

以下是如何做到这一点:

list = new LinkedList<T1>(
    list
    .GroupBy(x => x.param)
    .Where(x => x.Count() > 1)
    .SelectMany(x => x));

您可以根据param属性对项目进行分组(这类似于创建组列表,每个组都包含共享param属性值的项目)。

在您的示例中,这将创建7个组:

{A} ,{B,C,F},{D},{E},{G,I},{H},{J}

然后,通过只获取具有多个项目的组来筛选组(从而删除具有单个项目的组)。

当你保留有多个项目的组时,你保留{B,C,F}和{G,I}。

然后,通过SelectMany将组展平为单独的项目,得到{B,C,F,G,I}。

性能测试:

如果您的列表可能很大,那么您应该考虑性能。我提供的解决方案非常高效,以下是如何测试它并将其与其他解决方案进行性能比较:

List<T1> list = new List<T1>();
Random rnd = new Random();
for (int i = 0; i < 10000; i++)
{
    list.Add(new T1 { param = rnd.Next(1,5000).ToString()});
}
Stopwatch sw = Stopwatch.StartNew();
var result1 =
    list
        .GroupBy(x => x.param)
        .Where(x => x.Count() > 1)
        .SelectMany(x => x)
        .ToList();
long result1_time = sw.ElapsedMilliseconds;
sw.Restart();
var result2 = list.Where(el => list.Any(z => z.param == el.param && z != el)).ToList();
long result2_time = sw.ElapsedMilliseconds;
Console.WriteLine(result1_time);
Console.WriteLine(result2_time);
Console.ReadLine();

在我的机器上,我的解决方案需要大约3毫秒,而另一个解决方案需要2500毫秒。

这应该能在中工作

var b = list.Where(el => list.Any(z => z.param == el.param && z != el));