Supprimer les doublons dans la liste à l'aide de linq

J'ai une classe Items avec properties (Id, Name, Code, Price).

La liste de Items est remplie avec des éléments dupliqués.

Par ex.:

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

Comment supprimer les doublons dans la liste en utilisant linq?

235
demandé sur Çağdaş Tekin 2009-10-22 15:48:26

10 réponses

var distinctItems = items.Distinct();

Pour ne correspondre qu'à certaines propriétés, créez un comparateur d'égalité personnalisé, par exemple:

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

Ensuite, utilisez-le comme ceci:

var distinctItems = items.Distinct(new DistinctItemComparer());
324
répondu Christian Hayter 2009-10-22 12:10:59
var distinctItems = items.GroupBy(x => x.Id).Select(y => y.First());
493
répondu Freddy 2012-04-12 06:46:30

S'il y a quelque chose qui jette votre requête distincte, vous pouvez regarder MoreLinq et utiliser L'opérateur DistinctBy et sélectionner des objets distincts par id.

var distinct = items.DistinctBy( i => i.Id );
33
répondu tvanfosson 2009-10-22 12:00:16

C'est ainsi que J'ai pu me regrouper avec Linq. Espérons que cela aide.

var query = collection.GroupBy(x => x.title).Select(y => y.FirstOrDefault());
24
répondu Victor Juri 2014-06-19 07:43:52

Utilisez Distinct() mais gardez à l'esprit qu'il utilise le comparateur d'égalité par défaut pour comparer les valeurs, donc si vous voulez quelque chose au-delà, vous devez implémenter votre propre comparateur.

S'il vous plaît voir http://msdn.microsoft.com/en-us/library/bb348436.aspx pour un exemple.

15
répondu Brian Rasmussen 2010-03-05 19:25:00

Vous avez trois options ici pour supprimer l'élément en double dans votre liste:

  1. Utiliser un personnalisé comparateur d'égalité et ensuite utiliser Distinct(new DistinctItemComparer()), comme @Christian Hayter mentionné.
  2. Utilisez GroupBy, mais notez dans GroupBy que vous devez Grouper par toutes les colonnes car si vous groupez simplement par Id, cela ne supprime pas toujours les éléments en double. Par exemple, considérons l'exemple suivant:

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

    Le résultat de ce regroupement sera:

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

    Qui est incorrect car il considère {Id = 3, Name = "Item3", Code = "IT00004", Price = 250} comme dupliqué. Donc, la requête correcte serait:

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

    3.Remplacer Equal et GetHashCode dans la classe d'article:

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

    , Alors vous pouvez l'utiliser comme ceci:

    var distinctItems = a.Distinct();
    
12
répondu S.Akbari 2017-05-23 12:18:13
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
répondu Arun Kumar 2016-07-18 08:30:00

Essayez cette méthode d'extension. Espérons que cela pourrait aider.

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

Utilisation:

var outputList = sourceList.DistinctBy(x => x.TargetProperty);
2
répondu Kent Aguilar 2017-06-21 16:52:34

Une méthode d'extension universelle:

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

Exemple d'utilisation:

var lstDst = lst.DistinctBy(g => g.Key);
1
répondu TOL 2017-12-14 11:24:35

Lorsque vous ne voulez pas écrire IEqualityComparer, vous pouvez essayer quelque chose comme suit.

 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
répondu Kundan Bhati 2017-07-06 06:33:47