首页 / .NET / 正文

.NET[C#]使用LINQ从List<T>集合中删除重复对象元素(去重)的方法有哪些?

18791 2评论 发布于: 2018-01-15 读完约需10分钟

.NET[C#]使用LINQ从List<T>集合中删除重复对象元素(去重)的方法有哪些?

问题描述

比如有如下的List集合:

1         Item1       IT00001        $100
2         Item2       IT00002        $200
3         Item3       IT00003        $150
1         Item1       IT00001        $100
3         Item3       IT00003        $150

使用LINQ如何实现对以上List集合的去重操作,具体实现有哪些呢?

方案一

var distinctItems = items.Distinct();

如果需要对泛型实体中的部分属性进行去重操作,则可以创建一个自定义的比较器:

class DistinctItemComparer : IEqualityComparer<Item> {

    public bool Equals(Item x, Item y) {
        return x.Id == y.Id &&
            x.Name == y.Name &&
            x.Code == y.Code &&
            x.Price == y.Price;
    }

    public int GetHashCode(Item obj) {
        return obj.Id.GetHashCode() ^
            obj.Name.GetHashCode() ^
            obj.Code.GetHashCode() ^
            obj.Price.GetHashCode();
    }
}

调用方法:

var distinctItems = items.Distinct(new DistinctItemComparer());

方案二

var distinctItems = items.GroupBy(x => x.Id).Select(y => y.First());

方案三

使用 MoreLinq 组件:

var distinct = items.DistinctBy( i => i.Id );

方案四

var query = collection.GroupBy(x => x.title).Select(y => y.FirstOrDefault());

方案五

创建静态扩展方法,如:

public static class DistinctHelper
{
    public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
    {
        var identifiedKeys = new HashSet<TKey>();
        return source.Where(element => identifiedKeys.Add(keySelector(element)));
    }
}

调用方法:

var outputList = sourceList.DistinctBy(x => x.TargetProperty);

其中 x.TargetProperty 请替换成类对应的属性。

示例程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var people = new List<Person>
            {
                new Person {Id=1,Name="Curry",Age=26 },
                new Person {Id=1,Name="Curry",Age=26 },
                new Person {Id=3,Name="James",Age=27 },
                new Person {Id=4,Name="Kobe",Age=38 }
            };
            var distinctPeople = people.DistinctBy(x => x.Name).ToList();
            distinctPeople.ForEach(x =>
            Console.WriteLine($"Id:{x.Id},Name:{x.Name},Age:{x.Age}")
            );
            Console.ReadKey();
        }
    }

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

    public static class DistinctHelper
    {
        public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            var identifiedKeys = new HashSet<TKey>();
            return source.Where(element => identifiedKeys.Add(keySelector(element)));
        }
    }
}

方案六

public static class DistinctHelper
    {
        public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            var identifiedKeys = new HashSet<TKey>();

            foreach (var item in source)
            {
                if (identifiedKeys.Add(keySelector(item)))
                    yield return item;
            }
        }
    }

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

上一篇: .NET[C#]C#中如何使用反射调用泛型方法?

下一篇: [MySQL]MySQL数据库中如何使用SQL语句查看表或者列的所有外键?

本文永久链接码友网 » .NET[C#]使用LINQ从List<T>集合中删除重复对象元素(去重)的方法有哪些?

分享扩散:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册

热门评论

Rector (2018-01-15 18:47)

方案五是可以的,请见补充的示例程序
回复 赞(0)

CNXY (2018-01-15 15:48)

方案五在VS2017里试了一下,没有结果,改为以下就可以: public static class DistinctHelper { public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) { var identifiedKeys = new HashSet(); foreach(var item in source) { if (identifiedKeys.Add(keySelector(item))) yield return item; } } }
回复 赞(0)