equnex
equnex

Reputation: 3

How to remove duplicates from object list based on that object property in c#

I've got a problem with removing duplicates at runtime from my list of object.

I would like to remove duplicates from my list of object and then set counter=counter+1 of base object.

public class MyObject 
{
   MyObject(string name) 
   {
      this.counter = 0;
      this.name = name;
   }
   public string name;
   public int counter;
}

List<MyObject> objects_list = new List<MyObject>();
objects_list.Add(new MyObject("john"));
objects_list.Add(new MyObject("anna"));
objects_list.Add(new MyObject("john"));
foreach (MyObject my_object in objects_list) 
{
    foreach (MyObject my_second_object in objects_list) 
    {
        if (my_object.name == my_second_object.name) 
        {
           my_object.counter = my_object.counter + 1;
           objects_list.remove(my_second_object);
        }
    }
}

It return an error, because objects_list is modified at runtime. How can I get this working?

Upvotes: 0

Views: 163

Answers (2)

Ilya Chernomordik
Ilya Chernomordik

Reputation: 30235

The other answer seem to be correct, though I think it will do scan of the whole list twice, depending on your requirement this might or might not be good enough. Here is how you can do it in one go:

var dictionary = new Dictionary<string, MyObject>();
foreach(var obj in objects_list) 
{
  if(!dictionary.ContainsKey(obj.name)
  {
    dictionary[obj.name] = obj;
    obj.counter++;
  }
  else
  {
      dictionary[obj.name].counter++;
  } 
}

Then dictionary.Values will contain your collection

Upvotes: 0

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186748

With a help of Linq GroupBy we can combine duplicates in a single group and process it (i.e. return an item which represents all the duplicates):

 List<MyObject> objects_list = ...

 objects_list = objects_list
   .GroupBy(item => item.name)            
   .Select(group => {                            // given a group of duplicates we
      var item = group.First();                  // - take the 1st item
      item.counter = group.Sum(g => g.counter);  // - update its counter
      return item;                               // - and return it instead of group
    })
   .ToList();

Upvotes: 1

Related Questions