2011-06-30 6 views
2

J'ai une liste qui contient des valeurs d'éléments en double (par ID), mais avec une priorité différente (ou éventuellement égale). Les éléments en double ayant une priorité identique ou inférieure doivent être supprimés de la liste.Filtrage Linq distinct avec des critères supplémentaires

Par exemple:

var items = new { 
    new { Id=2, Priority=3 }, 
    new { Id=4, Priority=4 }, 
    new { Id=1, Priority=4 }, 
    new { Id=2, Priority=5 }, 
    new { Id=4, Priority=4 } 
}; 

RemoveDuplicates(items); 

// items should now contain distinct values, 
// with highest possible priority 
var items = new { 
    new { Id=1, Priority=4 }, // this one was unique 
    new { Id=2, Priority=5 }, // this one was duplicate with higher priority 
    new { Id=4, Priority=4 }, // this one was duplicate with same priority 
}; 

Est-il possible de le faire en utilisant LINQ? Je sais que je pourrais trier la liste par ID et ensuite vérifier les éléments adjacents, mais je voulais juste vérifier si cela est possible.

(update: valeurs d'entrée ne sont pas nécessairement regroupés par ID)

Répondre

3
 var items = new[] { 
      new { Id=2, Priority=3 }, 
      new { Id=2, Priority=5 }, 
      new { Id=1, Priority=4 }, 
      new { Id=4, Priority=4 }, 
      new { Id=4, Priority=4 } 
     }; 

     var deduped = items 
      .GroupBy(item => item.Id) 
      .Select(group => group.OrderByDescending(item => item.Priority).First()) 
      .OrderBy(item => item.Id); 
1

Les rendements Distinct Extension Method les éléments distincts d'une séquence. Vous pouvez fournir un IEqualityComparer <TSource> pour déterminer si deux éléments sont égaux. Cependant, la méthode ne vous permet pas de choisir lequel des deux éléments égaux est utilisé.

Vous pouvez utiliser le GroupBy Extension Method pour regrouper la liste par ID, puis sélectionnez l'élément avec la plus haute priorité de chaque groupe:

var query = items.GroupBy(item => item.Id) 
       .Select(g => g.MaxBy(item => item.Priority)) 
       .OrderBy(item => item.Id); 

utilisant MaxBy de MoreLINQ.

Questions connexes