user1357872
user1357872

Reputation: 803

Distinct in LINQ-C#

I have the below list and query expression to get the distinct list.

 List<LinqTest> myList = new List<LinqTest>();
 myList.Add(new LinqTest() { id = 1, value = "a" });
 myList.Add(new LinqTest() { id = 1, value = "b" });
 myList.Add(new LinqTest() { id = 2, value = "c" });
 myList.Select(m => new { m.id}).Distinct().ToList();

I have referred the below SO link linkfor the code. Even after using distinct() i'm getting 3 records with the duplicate values. what could be the reason?

Upvotes: 8

Views: 20892

Answers (6)

Alexander
Alexander

Reputation: 4537

In your case the Distinct() method uses the default equality comparer of anonimous type object. Therefore the result is not expected. If you want to get unique id values use

List<int> ListOfIDs = myList.Select(m => m.id).Distinct().ToList();

If you want to get distinct objects of a custom type, then you need to implement IEquatable generic interface and provide your own GetHashCode and Equals methods for the type. See MSDN for details.

Upvotes: 5

Santhosh
Santhosh

Reputation: 729

You are not storing the distinct list to anywhere. change you last line to assign the distinct values to a new variable.

 var distinctList = myList.Select(m => new { m.id}).Distinct().ToList();

Upvotes: 3

m1kael
m1kael

Reputation: 2851

Here's an example that does this (note Equals and GetHashCode methods):

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<LinqTest> myList = new List<LinqTest>();
            myList.Add(new LinqTest() { Id = 1, Value = "a" });
            myList.Add(new LinqTest() { Id = 1, Value = "b" });
            myList.Add(new LinqTest() { Id = 2, Value = "c" });

            var distinct = myList.Distinct().ToList();
        }

        class LinqTest
        {
            public override bool Equals(object obj)
            {
                var that = obj as LinqTest;
                return that == null ? false : Id == that.Id;
            }

            public override int GetHashCode()
            {
                return Id;
            }

            public int Id { get; set; }
            public string Value { get; set; }
        }
    }
}

Upvotes: 1

Damith
Damith

Reputation: 63105

Change your select as .Select(m => m.id), you are creating new object with id as property in it, then after get the distinct, when comparing objects will not give the exact distinct objects you need. you need to be specific, if you need to get distinct by property of object then use GROUP BY or MoreLinq, DistinctBy method. check answers of below question

Distinct in Linq based on only one field of the table

Upvotes: 2

touchofevil
touchofevil

Reputation: 613

The 3 records that you see at debug time is your existing list. I think all that you've missed is an assignment.

List<LinqTest> myList = new List<LinqTest>();
myList.Add(new LinqTest() { id = 1, value = "a" });
myList.Add(new LinqTest() { id = 1, value = "b" });
myList.Add(new LinqTest() { id = 2, value = "c" });
// not sure why new {m.id} was used in this context
List<int> distinctList = myList.Select(m => m.id).Distinct().ToList();

Upvotes: 12

Sajeetharan
Sajeetharan

Reputation: 222712

Use GroupBy,

var result  = myList 
  .GroupBy(p => p.id)
  .Select(g => g.First())
  .ToList();

Upvotes: 2

Related Questions