I have a class say
public class Sample
{
public string property;
public List<string> someListProperty;
public string someOtherPropery;
}
Now I have a object which is List<Sample>
, I need to iterate over this collection and find out items which are having same values for property
and someListProperty
fields.
I tried this:
var listSample = List<Sample>()
var result = listSample.GroupBy(x => new { x.property, x.someListProperty})
.Where(x => x.Count() > 1).ToList();
But this doesn't seem to work, any pointer would be greatly appreciated.
Update after comment below: As what you describe is that you want to group by someOtherProperty
instead of someListProperty
then just group by it:
listSample.GroupBy(x => new { x.property, x.someOtherProperty});
Option 1 - You should use the SequenceEqual
to check that the nested lists of two given samples are the same. To do that pass a custom IEqualityComparer
public class SampleComparer : IEqualityComparer<Sample>
{
public bool Equals(Sample x, Sample y)
{
return x.property == y.property &&
Enumerable.SequenceEqual(x.someListProperty, y.someListProperty);
}
public int GetHashCode(Sample obj)
{
// Implement
}
}
(for implementing the GetHashCode
see: What is the best algorithm for an overridden System.Object.GetHashCode?)
and then:
var result = list.GroupBy(k => k, new SampleComparer());
tested on the following data and it returns 3 groups:
List<Sample> a = new List<Sample>()
{
new Sample { property = "a", someListProperty = new List<string> {"a"}, someOtherPropery = "1"},
new Sample { property = "a", someListProperty = new List<string> {"a"}, someOtherPropery = "2"},
new Sample { property = "a", someListProperty = new List<string> {"b"}, someOtherPropery = "3"},
new Sample { property = "b", someListProperty = new List<string> {"a"}, someOtherPropery = "4"},
};
Option 2 - Instead of creating a class implementing the interface is to use the ProjectionEqualityComparer
as explained here: Can you create a simple 'EqualityComparer<T>' using a lambda expression
As a side note instead of using Count
in the where use:
var result = list.GroupBy(k => k, new SampleComparer())
.Where(g => g.Skip(1).Any());
As all you want is just to check there is more than one item in the group but not the actual amount this will just go through two items instead of counting them all in an O(n)
operation.