7

I have a list of objects that I need some duplicates removed from. We consider them duplicates if they have the same Id and prefer the one whose booleanValue is false. Here's what I have so far:

objects.GroupBy(x => x.Id).Select(x => x.Where(y => !y.booleanValue));

I've determined that GroupBy is doing no such grouping, so I don't see if any of the other functions are working. Any ideas on this? Thanks in advance.

2 Answers2

15

You can do this:

var results = 
    from x in objects
    group x by x.Id into g
    select g.OrderBy(y => y.booleanValue).First();

For every Id it finds in objects, it will select the first element where booleanValue == false, or the the first one (if none of them have booleanValue == false).

If you prefer fluent syntax:

var results = objects.GroupBy(x => x.Id)
                     .Select(g => g.OrderBy(y => y.booleanValue).First());
p.s.w.g
  • 141,205
  • 29
  • 278
  • 318
  • I do prefer fluent syntax. :) Thank you. As a side note for someone else who finds this, I added ".ToList()" after the last parenthesis and set "objects =" instead of "var results =". This way I could make permanent changes to the list, as it were. – Garrett Daniel DeMeyer Apr 11 '13 at 14:17
  • 1
    @p.s.w.g What if I dont want to remove all duplicates but always leave one left in the list? – Obsivus Jan 13 '15 at 13:43
  • I tried this, but it is not working for my list of objects. I still get duplicates returned. Please see my question: http://stackoverflow.com/questions/42316343/groupby-to-remove-duplicates-from-ienumerable-list-of-objects – naz786 Feb 20 '17 at 13:42
0

Something like this should work:

var result =
    objects.GroupBy(x => x.Id).Select(g =>
        g.FirstOrDefault(y => !y.booleanValue) ?? g.First())

This assumes that your objects are of a reference type.

Another possibility might be to use Distinct() with a custom IEqualityComparer<>.

BitCortex
  • 3,103
  • 1
  • 14
  • 18