-1

I'm trying to find all the duplicates in my ObservableCollection, using Lambda/LINQ Say I have my ObservableCollection<Student> studentList

Each Student has fields

Name
Age
Class

Now in the list, say the following is input in the list

studentList.Add(new Student()
    {
        Name = Name,
        Age= Age,
        Class = Class
    });

Each time the user enters the data and clicks the button, the data is added. So in my list I would have (as an example)

Bob, 6, Blue Class

Jerry 8, Red Class

Andy 7, Red Class

Bob, 10, Red Class

I would like to loop through the list and find out which names are duplicates So far my code is:

bool cont = false;
foreach (var dup in studentList)
    {
        if (!studentList.Any(x => x.Name== dup.Name))
            {
                cont = true;
            }
            else
            {
                cont = false;
                break;
            }
    }

But something is not right. It will always "Bob" in the if statement. And if I entered 4 completley different names, it would still say false. It takes the last entered value and always compares it to that one, never actually checking them all.

It is a bit hard to explain. If I knew where the problem lie, I would be of more help.

All I would like is to loop through my list to find matching values, and to set the bool to false and break the loop, so that the user can be notified and can make changes before they continue. And I would like the solution to be in a Lambda/LINQ statement

Community
  • 1
  • 1
Nicholas Aysen
  • 568
  • 3
  • 18
  • 40
  • 1
    I'm sure you will find answers to this question if you search a bit. Example http://stackoverflow.com/questions/18547354/c-sharp-linq-find-duplicates-in-list – Marcom Feb 24 '14 at 12:41
  • what you want to do with duplicate names? put this in new list? – Only a Curious Mind Feb 24 '14 at 12:45
  • @Marcom Have searched. Trying to of course find something that is similar to mine, which you might not always get. Still checking Google's results for the time being auntil there's a good answer – Nicholas Aysen Feb 24 '14 at 12:46
  • @LucasAbilidebob No. Just wan to return a true if there are any duplicate names. Thats why I have a bool and a break – Nicholas Aysen Feb 24 '14 at 12:47

4 Answers4

3
studentList.GroupBy(n => n.Name).Where(n => n.Count() > 1).Select(n => n.Key);

Explaination: This code first groups them by names creating a dictionary in form name => list of students with that name, then checks where there are more than one name and selects that names.

Migol
  • 8,161
  • 8
  • 47
  • 69
2

How about this:

bool anyDuplicates = studentList.Select(i => i.Name).Distinct().Count() 
                     < studentList.Count();

This checks if the Distinct list of names is smaller than the full list of students.

Baldrick
  • 11,712
  • 2
  • 31
  • 35
  • 1
    See OP's last comment: `No. Just wan to return a true if there are any duplicate names. Thats why I have a bool and a break` – Baldrick Feb 24 '14 at 13:13
0

According to your comment you don't need a foreach loop you can do this in one line:

bool control = studentList
               .Any(s => studentList.Count(x => x.Name == s.Name) > 1);
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
-1

EDIT

You can simply use the linq like below:

var duplicateNamesList = studentList.GroupBy(x => x.Name).Where(x => x.Count() > 1).Select(x => x.Key);

You have to implement IEqualityComparer<T> for your Student class like below:

public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Class { get; set; }

    public class EqualityComparer : IEqualityComparer<Student>
    {
        public bool Equals(Student x, Student y)
        {
            return x.Name == y.Name;
        }

        public int GetHashCode(Student obj)
        {
            unchecked  // overflow is fine
            {
                int hash = 17;
                hash = hash * 23 + obj.Name.GetHashCode();
                return hash;
            }
        }
    }
}

Then just invoke studentList.Distinct(new Student.EqualityComparer()) and assign it back to studentList like below:

studentList = studentList.Distinct(new Student.EqualityComparer()).ToList();
Wasif Hossain
  • 3,900
  • 1
  • 18
  • 20