Remove duplicates from array structs

I know two ways to remove duplicates from an array of objects that support explicit comparison:

  • Using the HashSet constructor and
  • Using LINQ Distinct ().

How to remove duplicates from an array of structures by comparing array elements with only one field? In other words, how to write a predicate that Distinct () can use.

Hello,

+4
source share
4 answers

Well, you can implement IEqualityComparer<T> to select this field and use it to test equality and hashing ... or you can use DistinctBy , which is in MoreLINQ .

Of course, you do not need to depend on MoreLINQ - you can implement it very simply:

 public static IEnumerable<TSource> DistinctBy<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) { // TODO: Implement null argument checking :) HashSet<TKey> keys = new HashSet<TKey>(); foreach (TSource element in source) { if (knownKeys.Add(keySelector(element))) { yield return element; } } } 
+5
source

I would probably just loop:

 var values = new HashSet<FieldType>(); var newList = new List<ItemType>(); foreach(var item in oldList) { if(hash.Add(item.TheField)) newList.Add(item); } 
+3
source

LINQ's answer was posted earlier. I copy from Richard Salai the answer here: Filtering duplicates from IEnumerable

 public static class EnumerationExtensions { public static IEnumerable<TSource> Distinct<TSource,TKey>( this IEnumerable<TSource> source, Func<TSource,TKey> keySelector) { KeyComparer comparer = new KeyComparer(keySelector); return source.Distinct(comparer); } private class KeyComparer<TSource,TKey> : IEqualityComparer<TSource> { private Func<TSource,TKey> keySelector; public DelegatedComparer(Func<TSource,TKey> keySelector) { this.keySelector = keySelector; } bool IEqualityComparer.Equals(TSource a, TSource b) { if (a == null && b == null) return true; if (a == null || b == null) return false; return keySelector(a) == keySelector(b); } int IEqualityComparer.GetHashCode(TSource obj) { return keySelector(obj).GetHashCode(); } } } 

Which, as Richard says, is used as follows:

 var distinct = arr.Distinct(x => x.Name); 
+2
source

implement custom IEqualityComparer<T>

 public class MyStructComparer : IEqualityComparer<MyStruct> { public bool Equals(MyStruct x, MyStruct y) { return x.MyVal.Equals(y.MyVal); } public int GetHashCode(MyStruct obj) { return obj.MyVal.GetHashCode(); } } 

then

 var distincts = myStructList.Distinct(new MyStructComparer()); 
+1
source

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


All Articles