it-swarm.com.de

Entfernen Sie Duplikate in der Liste mit linq

Ich habe eine Klasse Items mit properties (Id, Name, Code, Price).

Die Liste von Items wird mit doppelten Elementen gefüllt. 

ZB: 

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

Wie entferne ich die Duplikate aus der Liste mit linq?

252
Prasad
var distinctItems = items.Distinct();

Um nur einige der Eigenschaften abzugleichen, erstellen Sie einen benutzerdefinierten Gleichheitsvergleicher, z. B .:

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

Dann benutze es so:

var distinctItems = items.Distinct(new DistinctItemComparer());
339
var distinctItems = items.GroupBy(x => x.Id).Select(y => y.First());
522
Freddy

Wenn etwas von Ihrer Distinct-Abfrage abgeworfen wird, möchten Sie vielleicht nach MoreLinq suchen und den DistinctBy-Operator verwenden und anhand der ID unterschiedliche Objekte auswählen.

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

So konnte ich mich mit Linq zusammenschließen. Ich hoffe es hilft.

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

Verwenden Sie Distinct(), beachten Sie jedoch, dass der Standardgleichheitsvergleicher zum Vergleichen von Werten verwendet wird. Wenn Sie darüber hinausgehende Werte wünschen, müssen Sie einen eigenen Vergleicher implementieren. 

Unter http://msdn.Microsoft.com/de-de/library/bb348436.aspx finden Sie ein Beispiel. 

15
Brian Rasmussen

Sie haben hier drei Möglichkeiten, doppelte Elemente in Ihrer Liste zu entfernen:

  1. Verwenden Sie einen benutzerdefinierten Gleichheitsvergleicher und verwenden Sie dann Distinct(new DistinctItemComparer()) als @Christian Hayter .
  2. Verwenden Sie GroupBy, beachten Sie aber bitte, dass Sie in GroupBy nach allen Spalten gruppieren sollten, denn wenn Sie nur nach Id gruppieren, werden doppelte Elemente nicht immer entfernt. Betrachten Sie zum Beispiel das folgende Beispiel:

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

    Das Ergebnis für diese Gruppierung ist:

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

    Was falsch ist, weil es {Id = 3, Name = "Item3", Code = "IT00004", Price = 250} als Duplikat betrachtet. Die korrekte Abfrage wäre also:

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

    3. Überschreiben Sie Equal und GetHashCode in der Elementklasse:

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

    Dann kannst du es so benutzen:

    var distinctItems = a.Distinct();
    
12
S.Akbari

Eine universelle Erweiterungsmethode:

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

Verwendungsbeispiel:

var lstDst = lst.DistinctBy(g => g.Key);
3
TOL
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();
3
Arun Kumar

Probieren Sie diese Erweiterungsmethode aus. Hoffentlich könnte das helfen.

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

Verwendungszweck:

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

Wenn Sie nicht IEqualityComparer schreiben möchten, können Sie Folgendes versuchen. 

 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; }
}
0
Kundan Bhati