user70192
user70192

Reputation: 14204

LINQ Distinct Query

I have a C# application that loads a List of CLR objects called "Tasks". Each Task has the following properties:

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

I am trying to find the unique types of tasks in this list. I thought I would try to use LINQ to do it. However, I cannot figure out how to do it. How do I say give me all of the unique TypeID and TypeName in this list? Currently I'm trying the following which is getting me no where. In fact, it wound even compile.

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

Thank you,

Upvotes: 2

Views: 14972

Answers (4)

James Curran
James Curran

Reputation: 103485

 var uniqueTasks = allTasks.Select(t=>t.TypeName).Distinct().ToList();

Upvotes: 2

SLaks
SLaks

Reputation: 887195

The simplest way to do this is to use GroupBy:

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

This will give you a set of groupings that map a TypeID to the tasks with that ID.

If you want a set of tasks, you can write

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

Upvotes: 3

BFree
BFree

Reputation: 103742

You need to implement your own comparer:

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
}

Then use it like this:

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

EDIT: Hacked out some GetHashCode() thanks to Slaks who pointed out that GetHashCode is absolutely necessary (I guess it builds a HashTable internally)

Upvotes: 2

Eric Lippert
Eric Lippert

Reputation: 659956

Let me make sure I understand the problem: you have a sequence of tasks called allTasks, and you would like a sequence without duplicates of all the ids, yes?

Transform the sequence of tasks into a sequence of ids:

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

Now you have a sequence of ids. You wish to filter out the duplicates from that sequence:

var distinctIds = ids.Distinct();

And you're done. Is that what you were after?

Upvotes: 6

Related Questions