2010-02-24 6 views
1

J'ai une application C# qui charge une liste d'objets CLR appelée "Tâches". Chaque tâche a les propriétés suivantes:LINQ Distinct Query

public int ID { get; set; } 
public int TypeID { get; set; } 
public string TypeName { get; set; } 
public string Name { get; set; } 

J'essaie de trouver les types uniques de tâches dans cette liste. J'ai pensé que j'essaierais d'utiliser LINQ pour le faire. Cependant, je ne peux pas comprendre comment le faire. Comment puis-je me donner tous les TypeID unique et TypeName dans cette liste? Actuellement, j'essaie ce qui suit qui ne m'amène nulle part. En fait, il a même enroulé la compilation.

var uniqueTasks = allTasks.Distinct(p => p.TypeID); 

Merci,

+0

Voulez-vous les tâches distinctes ou les types distincts? – SLaks

+2

Voulez-vous une liste des TypeID distincts et une liste de TypeNames distincts ou une liste de paires distinctes TypeID, TypeName? – user76035

Répondre

6

Permettez-moi que je comprends le problème: vous avez une séquence de tâches appelées Toutes les tâches, et que vous souhaitez une séquence sans doublons de tous les ids, oui?

Transformer la séquence de tâches en une séquence de ids:

var ids = allTasks.Select(p=>p.TypeId); 

Maintenant vous avez une séquence de ids. Vous souhaitez filtrer les doublons de cette séquence:

var distinctIds = ids.Distinct(); 

Et vous avez terminé. C'est ce que tu cherchais?

+0

C'est une façon cool de le faire. Mais votre 'var ids 'ou' var distinctIds' est une liste de 'int'. pas la liste originale des 'objets' appelée' Task'. Que faire si je veux utiliser une autre chose de 'Task' comme' TypeName'? J'ai besoin d'interroger à nouveau la liste d'organisation pour saisir les informations nécessaires. – william

2

Vous devez implémenter votre propre comparateur:

public class TaskComparer : IEqualityComparer<Task> 
{ 

    #region IEqualityComparer<Task> Members 

    public bool Equals(Task x, Task y) 
    { 
     return x.TypeID == y.TypeID && x.TypeName == y.TypeName; 
    } 

    public int GetHashCode(Task obj) 
    { 
     return obj.TypeID.GetHashCode() + obj.TypeName.GetHashCode(); 
    } 

    #endregion 
} 

utiliser ensuite comme ceci:

var uniqueTasks = allTasks.Distinct(new TaskComparer()); 

EDIT: hacké quelques-uns grâce à Slaks GetHashCode() qui a fait remarquer que GetHashCode est absolument nécessaire (je suppose qu'il construit un HashTable en interne)

+0

MAUVAIS MAUVAIS! ** Vous _MUST_ implémenter 'GetHashCode'! ** – SLaks

+0

Vraiment? Pourquoi ça? – BFree

+0

Parce que sinon, ce sera complètement inutile. – SLaks

3

La façon la plus simple de faire cela est d'utiliser GroupBy:

var uniqueTasks = allTasks.GroupBy(p => p.TypeID); 

Cela vous donnera un ensemble de groupements qui tracent une TypeID aux tâches avec cet ID.

Si vous voulez un ensemble de tâches, vous pouvez écrire

var uniqueTasks = allTasks.GroupBy(p => p.TypeID).Select(g => g.First()); 
1
var uniqueTasks = allTasks.Select(t=>t.TypeName).Distinct().ToList(); 
+0

t => t.TypeName;) – user76035

+0

@wwosik ... Merci ... Je devrais vraiment lire les choses que je poste ... –