Distinct in linq?

45,888

Solution 1

This populates both the Text and Value fields:

   myCollection.Select(x => x.Name).Distinct()
      .Select(x => new MyClassToStore { Text = x, Value = x }).ToList();

Solution 2

Maybe something like this can help?

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

Solution 3

If you just want back distinct names, you can use:

myCollection.Select(x => x.Name).Distinct().ToList();

Solution 4

You can implement your class so the linq distinct operator does not use the default equality comparer.

class YourClass:IEquatable<YourClass> 
{

... Your implementation details. ...

    public bool Equals(YourClass other)
    {
        if (Object.Equals(this, other))
        {
            return true;
        }
        else
        {
            if(Name == other.Name && Value == other.Value)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

 public override int GetHashCode()
 {
     return Name.GetHashCode() ^ Value.GetHashCode();
 }

}

Solution 5

Personally I suggest you override operator == and != and determine how and why an object is unique there. Then use the Distinct() call on the collection.

You do have to be careful with null values, see Microsoft's Guidelines for Overloading Equals() and Operator == (C# Programming Guide).

Share:
45,888
chobo2
Author by

chobo2

Updated on July 27, 2022

Comments

  • chobo2
    chobo2 almost 2 years

    I am wondering how can I achieve this?

    I want to get only distinct names from a collection of objects

    MyObject a = new Object();
    a.Name = 'One';
    a.Value = '10';
    
    
    MyObject b = new Object();
    b.Name = 'One';
    b.Value = '15';
    
    
    MyObject c = new Object();
    c.Name = 'Two';
    c.Value = '10';
    

    So I want to get only back the name. I don't care about the value in this case just the name.

    So I tried

    //add all the objects to a collection.

    myCollection.Disinct()..Select(x => new MyClassToStore() {Text = x.Name, Value = x.Name}).ToList());
    

    However I need to do distinct at the property level not at the object level. So I want back "One" and "Two". Right now I get "One", "One" and "Two" back.

    I see a library called morelinq but I not sure if I should use it as it still in beta and does not seem to be developed on anymore.

    Plus a whole library for one extract query I am not sure if it is worth it.

  • chobo2
    chobo2 about 13 years
    how could I get stick it into MyClassToStore
  • Marino Šimić
    Marino Šimić about 13 years
    var distinctitems = myCollection.GroupBy(x => x.Name).Select(x => x.First()).Select(new MyClassToStore() {Text = x.Name, Value = x.Name}) i suppose, altough i did not get exactly what you need. because using the same property (name) twice is a bit awkward... I think that you should listen to Cameron if you need just names...
  • Andy_Vulhop
    Andy_Vulhop over 10 years
    To be clear, do not override the == or != operator in any sort of global context. What's suggested here is to override the Equals and == operator your class inherits from object