Reputation: 307
say I have a list containing objects like this one:
public class Person
{
private string _name;
private string _id;
private int _age;
public Person
{
}
// Accessors
}
public class ManipulatePerson
{
Person person = new Person();
List<Person> personList = new List<Person>;
// Assign values
private void PopulateList();
{
// Loop
personList.Add(person);
// Check if every Person has a unique ID
}
}
and I wanted to check that each Person had a unique ID. I would like to return a boolean true/false depending on whether or not the IDs are unique. Is this something I can achieve with LINQ?
Upvotes: 8
Views: 7172
Reputation: 6744
I would use Distinct and then check against the counts for example:
bool bAreAllPeopleUnique = (personList.Distinct(p => p.ID).Count == personList.Count);
However as @Ian commented you will need to add a property to the Person
class so that you can access the Id like so:
public string ID
{
get { return _id; }
}
A 'nicer' way to implement this would be to add a method like so:
private bool AreAllPeopleUnique(IEnumerable<Person> people)
{
return (personList.Distinct(p => p.ID).Count == personList.Count);
}
NOTE: The method takes in an IEnumerable
not a list so that any class implementing that interface can use the method.
Upvotes: 7
Reputation: 64923
One of best ways to do so is overriding Equals
and GetHashCode
, and implementing IEquatable<T>
:
public class Person : IEquatable<Person>
{
public string Id { get; set; }
public override bool Equals(object some) => Equals(some as Person);
public override bool GetHashCode() => Id != null ? Id.GetHashCode() : 0;
public bool Equals(Person person) => person != null && person.UniqueId == UniqueId;
}
Now you can use HashSet<T>
to store unique objects and it will be impossible that you store duplicates. And, in addition, if you try to add a duplicated item, Add
will return false
.
NOTE: My IEquatable<T>
, and Equals
/GetHashCode
overrides are very basic, but this sample implementation should give you a good hint on how to elegantly handle your scenario.
You can check this Q&A to get an idea on how to implement GetHashCode
What is the best algorithm for an overridden System.Object.GetHashCode?
Maybe this other Q&A might be interesitng for you: Why is it important to override GetHashCode when Equals method is overridden?
Upvotes: 1
Reputation: 111860
Note that you can even leverage directly an HashSet<>
:
var hs = new HashSet<string>();
bool areAllPeopleUnique = personList.All(x => hs.Add(x.Id));
(and is the code that I normally use)
It has the advantage that on the best case (presence of some duplicates) it will stop before analyzing all the personList
collection.
Upvotes: 10
Reputation: 10824
You can use GroupBy
for getting unique items:
var result = personList.GroupBy(p=> p.Id)
.Select(grp => grp.First())
.ToList();
Upvotes: 0