1

I have a list and in the list there are multiple entries. If the list contains an entry that is duplicated then I want to only keep one of the duplicates.

I've tried many things, the list.Distinct().ToList() and this does not remove the duplicate entry, I do not want to override the classes Equals method, so is there a way outside of that.

I've also done this method which seems to again, not remove the duplicate entry as it does not consider object a == object b.

private void removeDupes(List<Bookings> list)
        {
            int duplicates = 0;
            int previousIndex = 0;

            for (int i = 0; i < list.Count; i++)
            {
                bool duplicateFound = false;
                for (int x = 0; x < i; x++)
                {
                    if (list[i] == list[x])
                    {
                        duplicateFound = true;
                        duplicates++;
                        break;
                    }
                }
                if (duplicateFound == false)
                {
                    list[previousIndex] = list[i];
                    previousIndex++;
                }
            }
        }
  • Would a `HashSet` solve your issue? This would prevent duplicates from being added. – C.Evenhuis Dec 01 '15 at 09:31
  • I've tried HashSet also but that does not work neither. –  Dec 01 '15 at 09:31
  • `list.Distinct().ToList()` does not remove the entry of `list` instance. It creates a new list instance. Does `list = list.Distinct().ToList()` help? – Sebastian Schumann Dec 01 '15 at 09:32
  • 1
    Possible duplicate of [C#, Get a list of distinct values in List](http://stackoverflow.com/questions/10255121/c-get-a-list-of-distinct-values-in-listfoo) – Paddy Dec 01 '15 at 09:32
  • @TheAkhemist you can supply a custom comparer to the constructor of the `HashSet`: see http://stackoverflow.com/a/1023475/292411 – C.Evenhuis Dec 01 '15 at 09:32
  • 4
    There are 2 rules you must first define, what is the logic that determines a booking to be a duplicate, and when there is a duplicate which booking do you want to keep if they are not identical. – Chris Chilvers Dec 01 '15 at 09:33
  • @Verarind yes ive tried list newlist = oldList.Distinct().ToList() and it doesnt work. –  Dec 01 '15 at 09:34

2 Answers2

2

There is another overload of the Distinct LINQ extension method that also takes an IEqualityComparer as an argument (see this link). So you'd need to create a class that implements IEqualityComparer<Bookings> and supply an instance of it to the Distinct-method. This way, you do not need to override the Equals method of the type.

The rules on whether two objects are equal to one another are implemented in the EqualityComparer.

As an alternative, you can use a HashSet and supply the EqualityComparer in the constructor.

Markus
  • 20,838
  • 4
  • 31
  • 55
  • Good answer, perhaps instead of "Distinct method" (which implies a method on the List class) you could say "Distinct LINQ extension" – Peter Morris Dec 01 '15 at 09:38
0

A possible solution for your problem in order of Markus answer might look like this:

public class Booking
    {
        public Booking(int id, float amount)
        {
            BookingId = id;
            BookingAmount = amount;
        }

        public int BookingId { get; }
        public float BookingAmount { get; }
    }

    public class BookingComparer : IEqualityComparer<Booking>
    {
        public bool Equals(Booking x, Booking y)
        {
            return (x.BookingAmount == y.BookingAmount) && (x.BookingId == y.BookingId);
        }

        public int GetHashCode(Booking obj)
        {
            return obj.BookingId.GetHashCode()*17 + obj.BookingAmount.GetHashCode()*17;
        }
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            var booking1 = new Booking(1, 12);
            var booking2 = new Booking(1, 12);

            var bookings = new List<Booking>();
            bookings.Add(booking1);
            bookings.Add(booking2);

            var result = bookings.Distinct(new BookingComparer()).ToList();
        }
    }
Kris
  • 956
  • 1
  • 12
  • 23