Question

J'ai une classe Articles avec propriétés (Id, Nom, Code, Prix) .

La liste des éléments contient des éléments dupliqués.

Par exemple:

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

Comment supprimer les doublons de la liste avec linq?

Était-ce utile?

La solution

var distinctItems = items.Distinct();

Pour ne faire correspondre que 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());

Autres conseils

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

Si quelque chose rejette votre requête Distinct, consultez MoreLinq et utilisez l'opérateur DistinctBy pour sélectionner des objets distincts par identifiant.

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

C’est ainsi que j’ai pu grouper avec Linq. J'espère que ça aide.

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

Utilisez Distinct () , mais n'oubliez pas qu'il utilise le comparateur d'égalité par défaut pour comparer les valeurs. Par conséquent, si vous souhaitez utiliser autre chose que cela, vous devez implémenter votre propre comparateur.

Veuillez consulter http://msdn.microsoft.com/en-us/ bibliothèque / bb348436.aspx pour un exemple.

Vous avez ici trois options pour supprimer les éléments en double de votre liste:

  1. Utilisez un comparateur d'égalité personnalisé, puis utilisez Distinct (new DistinctItemComparer ()) comme @Christian Hayter mentionné.
  2. Utilisez GroupBy , mais veuillez noter que dans GroupBy , vous devez regrouper toutes les colonnes, car si vous ne faites que grouper par Id il 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}
    

    Ce qui est incorrect car il considère que {Id = 3, Name = "Item3", Code = "IT00004", Price = 250} est 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.Override Égal et GetHashCode dans la classe de poste:

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

    Ensuite, vous pouvez l'utiliser comme ceci:

    var distinctItems = a.Distinct();
    

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

Essayez cette méthode d’extension. J'espère 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);

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; }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top