Can I use LINQ to check if the objects in the list have a unique identifier?

Let's say I have a list containing objects like this:

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 identifier. I would like to return a boolean value of true / false depending on whether the identifiers are unique. Is it possible to achieve this with LINQ?

+5
source share
4 answers

Note that you can even use the HashSet<> directly:

 var hs = new HashSet<string>(); bool areAllPeopleUnique = personList.All(x => hs.Add(x.Id)); 

(and this is the code that I usually use)

This has the advantage that in the best case (the presence of some duplicates) it will stop before analyzing the entire personList collection.

+4
source

I would use Distinct , and then, for example, check against count:

 bool bAreAllPeopleUnique = (personList.Distinct(p => p.ID).Count == personList.Count); 

However, as @Ian commented, you need to add a property to the Person class so that you can access the Id like this:

 public string ID { get { return _id; } } 

"Better" to implement this would be to add a method like this:

 private bool AreAllPeopleUnique(IEnumerable<Person> people) { return (personList.Distinct(p => p.ID).Count == personList.Count); } 

NOTE. The method accepts an IEnumerable not a list, so any class that implements this interface can use this method.

+6
source

One of the best ways to do this is to override Equals and GetHashCode and implement 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 you will not be able to store duplicates. In addition, if you try to add a duplicate element, Add will return false .

NOTE. My overrides of IEquatable<T> and Equals / GetHashCode very simple, but this sample implementation should give you good advice on how to elegantly handle your script.

You can check this Q&A to get an idea of ​​how to implement GetHashCode What is the best algorithm for an overridden System.Object.GetHashCode?

Perhaps this other Q&A might be of interest to you: Why is it important to override GetHashCode when the Equals method is overridden?

+1
source

You can use GroupBy to get unique elements:

 var result = personList.GroupBy(p=> p.Id) .Select(grp => grp.First()) .ToList(); 
0
source

Source: https://habr.com/ru/post/1243408/


All Articles