Reputation: 11
I have a list which consists of the following properties:
public class Category
{
public int RecordId { get; set;}
public string Category { get; set;}
public Data DataObj { get; set;}
}
My list is defined as List<Category>
categories.
The data class holds the following properties:
{
Id: 1,
Name: "Smith",
Input: "7,8",
Output: "Output1",
CreatedBy: "swallac",
CreatedON: "12/01/2018"
},
{
Id: 3,
Name: "Austin",
Input: "9,10",
Output: "Output1",
CreatedBy: "amanda",
CreatedON: "12/03/2018"
},
{
Id: 2,
Name: "Austin",
Input: "9,10",
Output: "Output1",
CreatedBy: "amanda",
CreatedON: "12/03/2018"
}
How can I get the duplicate item in the Data object?
I have tried the following but does not seem to return me the correct results.
var categoriesFiltered = categories.Select(g => g.DataObj);
var duplicateDataa = categoriesFiltered.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(y => y.Key);
Upvotes: 1
Views: 123
Reputation: 17085
You can use an Equality Comparer:
class MyComparer : IEqualityComparer<Category>
{
public bool Equals(Category? x, Category? y)
{
return x?.DataObj.Name == y?.DataObj.Input &&
x?.DataObj.Input == y?.DataObj.Input &&
x?.DataObj.Output == y?.DataObj.Output;
}
public int GetHashCode(Category obj)
{
return obj.DataObj.Name.GetHashCode() +
obj.DataObj.Input.GetHashCode() +
obj.DataObj.Output.GetHashCode();
}
}
Then use that comparer to make a distinction between your items:
var distinctList = categoriesFiltered.Distinct(new MyComparer());
Alternatively you can implement IEquatable<T>
on any class that needs to be compared in an arbitrary way:
public class Category : IEquatable<Category>
{
public int RecordId { get; set;}
public string Category { get; set;}
public Data DataObj { get; set;}
public bool Equals(Category? other)
{
return DataObj.Equals(other?.DataObj);
}
}
public class Data : IEquatable<Data>
{
...
public bool Equals(Data? other)
{
return Name.Equals(other?.Name) && Input.Equals(other?.Input) && ...;
}
}
Then let C# use them:
var distinctList = categoriesFiltered.Distinct();
If you want to know which items are removed as duplicate you can use Except
:
duplicates = categoriesFiltered.Except(distinctList);
Upvotes: 2
Reputation: 36341
You are probably lacking a equalitycomparer.
Since Category
is a class without an equals method it will default to reference equality. There are several ways to define equality of objects.
IEqualityComparer<Category>
, use this class as input to your Distinct
call. This allow multiple different ways to compare the same type.Category
Implement IEquatable<Category>
Equals(object)
method.Upvotes: 1