Using GroupBy()
and Count() > 1
I'm trying to find duplicate instances of my class in a list.
The class looks like this:
public class SampleObject
{
public string Id;
public IEnumerable<string> Events;
}
And this is how I instantiate and group the list:
public class Program
{
private static void Main(string[] args)
{
var items = new List<SampleObject>()
{
new SampleObject() { Id = "Id", Events = new List<string>() { "ExampleEvent" } },
new SampleObject() { Id = "Id", Events = new List<string>() { "ExampleEvent" } }
};
var duplicates = items.GroupBy(x => new { Token = x.Id, x.Events })
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.ToList();
}
}
The duplicates
contains no items. How can I make the grouping work?
The Linq GroupBy in C# belongs to the Grouping Operators category and exactly does the same thing as the Group By clause does in SQL Query. This method takes a flat sequence of elements and then organizes the elements into groups (i.e. IGrouping<TKey, TSource>) based on a given key.
In a Visual C# or Visual Basic query expression, the element and key selection expressions occur in the reverse order from their argument positions in a call to the GroupBy<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>) method.
Found answer on MSDN: Yes.
Groupby preserves the order of rows within each group. When calling apply, add group keys to index to identify pieces. Reduce the dimensionality of the return type if possible, otherwise return a consistent type.
To get objects to work with many of LINQ's operators, such as GroupBy
or Distinct
, you must either implement GetHashCode
& Equals
, or you must provide a custom comparer.
In your case, with a property as a list you probably need a comparer, unless you made the list read only.
Try this comparer:
public class SampleObjectComparer : IEqualityComparer<SampleObject>
{
public bool Equals(SampleObject x, SampleObject y)
{
return x.Id == y.Id && x.Events.SequenceEqual(y.Events);
}
public int GetHashCode(SampleObject x)
{
return x.Id.GetHashCode() ^ x.Events.Aggregate(0, (a, y) => a ^ y.GetHashCode());
}
}
Now this code works:
var items = new List<SampleObject>()
{
new SampleObject() { Id = "Id", Events = new List<string>() { "ExampleEvent"} },
new SampleObject() { Id = "Id", Events = new List<string>() { "ExampleEvent" } }
};
var comparer = new SampleObjectComparer();
var duplicates = items.GroupBy(x => x, comparer)
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.ToList();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With