9

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.

3 Answers3

19

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
  • 146,324
  • 30
  • 291
  • 331
  • 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,328
  • 1
  • 15
  • 19
0

This partially answers the question above, but I justed need a really basic solution:

objects.GroupBy(x => x.Id)
       .Select(x => x.First())
       .ToArray();

The key to getting the original object from the GroupBy() is the Select() getting the First() and the ToArray() gets you an array of your objects, not a Linq object.

Michael
  • 484
  • 6
  • 8