Вопрос

У меня есть занятие Items с properties (Id, Name, Code, Price).

Список из Items заполняется дублирующимися элементами.

Например:

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

Как удалить дубликаты в списке с помощью linq?

Это было полезно?

Решение

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 , используйте оператор DistinctBy и выберите отдельные объекты по идентификатору.

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

Так я смог сгруппироваться с Linq. Надеюсь, это поможет.

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

Используйте Distinct () , но имейте в виду, что для сравнения значений он использует компаратор равенства по умолчанию, поэтому, если вам нужно что-то еще, вам нужно реализовать свой собственный компаратор.

Пожалуйста, смотрите http://msdn.microsoft.com/en-us/ library / bb348436.aspx для примера.

У вас есть три варианта удаления дубликатов в вашем списке:

<Ол>
  • Используйте пользовательский сравнитель равенства, а затем используйте Distinct (новый DistinctItemComparer ()) как @Christian Hayter упомянуто.
  • Используйте GroupBy , но обратите внимание, что в GroupBy вы должны группировать по всем столбцам, потому что если вы просто группируете по Id он не удаляет дубликаты всегда. Например, рассмотрим следующий пример:

    List<Item> a = new List<Item>
    {
        new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100},
        new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200},
        new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150},
        new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100},
        new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150},
        new Item {Id = 3, Name = "Item3", Code = "IT00004", Price = 250}
    };
    var distinctItems = a.GroupBy(x => x.Id).Select(y => y.First());
    

    Результатом этой группировки будет:

    {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}
    {Id = 2, Name = "Item2", Code = "IT00002", Price = 200}
    {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}
    

    Это неверно, поскольку он считает {Id = 3, Name = " Item3 " ;, Code = " IT00004 " ;, Price = 250} как дубликат. Таким образом, правильный запрос будет:

    var distinctItems = a.GroupBy(c => new { c.Id , c.Name , c.Code , c.Price})
                         .Select(c => c.First()).ToList();
    

    3. Переопределить Equal и GetHashCode в классе элементов:

    public class Item
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Code { get; set; }
        public int Price { get; set; }
    
        public override bool Equals(object obj)
        {
            if (!(obj is Item))
                return false;
            Item p = (Item)obj;
            return (p.Id == Id && p.Name == Name && p.Code == Code && p.Price == Price);
        }
        public override int GetHashCode()
        {
            return String.Format("{0}|{1}|{2}|{3}", Id, Name, Code, Price).GetHashCode();
        }
    }
    

    Тогда вы можете использовать это так:

    var distinctItems = a.Distinct();
    
  • Универсальный метод расширения:

    public static class EnumerableExtensions
    {
        public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> enumerable, Func<T, TKey> keySelector)
        {
            return enumerable.GroupBy(keySelector).Select(grp => grp.First());
        }
    }
    

    Пример использования:

    var lstDst = lst.DistinctBy(item => item.Key);
    
    List<Employee> employees = new List<Employee>()
    {
        new Employee{Id =1,Name="AAAAA"}
        , new Employee{Id =2,Name="BBBBB"}
        , new Employee{Id =3,Name="AAAAA"}
        , new Employee{Id =4,Name="CCCCC"}
        , new Employee{Id =5,Name="AAAAA"}
    };
    
    List<Employee> duplicateEmployees = employees.Except(employees.GroupBy(i => i.Name)
                                                 .Select(ss => ss.FirstOrDefault()))
                                                .ToList();
    

    Попробуйте этот метод расширения.Надеюсь, это могло бы помочь.

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

    Если вы не хотите писать IEqualityComparer, вы можете попробовать что-то вроде следующего.

     class Program
    {
    
        private static void Main(string[] args)
        {
    
            var items = new List<Item>();
            items.Add(new Item {Id = 1, Name = "Item1"});
            items.Add(new Item {Id = 2, Name = "Item2"});
            items.Add(new Item {Id = 3, Name = "Item3"});
    
            //Duplicate item
            items.Add(new Item {Id = 4, Name = "Item4"});
            //Duplicate item
            items.Add(new Item {Id = 2, Name = "Item2"});
    
            items.Add(new Item {Id = 3, Name = "Item3"});
    
            var res = items.Select(i => new {i.Id, i.Name})
                .Distinct().Select(x => new Item {Id = x.Id, Name = x.Name}).ToList();
    
            // now res contains distinct records
        }
    
    
    
    }
    
    
    public class Item
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
    }
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top