I want to get the distinct values in a list, but not by the standard equality comparison.
What I want to do is something like this:
return myList.Distinct( (x, y) => x.Url == y.Url );
I can't, there's no extension method in Linq that will do this - just one that takes an IEqualityComparer
.
I can hack around it with this:
return myList.GroupBy( x => x.Url ).Select( g => g.First() );
But that seems messy. It also doesn't quite do the same thing - I can only use it here because I have a single key.
I could also add my own:
public static IEnumerable<T> Distinct<T>( this IEnumerable<T> input, Func<T,T,bool> compare ) { //write my own here }
But that does seem rather like writing something that should be there in the first place.
Anyone know why this method isn't there?
Am I missing something?
This is because the var temp = books. SelectMany(book => book. Authors). Distinct(); returns an IEnumerable , meaning that the request is not executed right away, it is only executed when the data is used.
LINQ Distinct operator removes all the duplicate values from the collection and finally returns the dissimilar or unique values. The LINQ Distinct operator available in only Method Syntax and it not supports the Query Syntax. LINQ Distinct is an operator which comes under Set Operator.
distinct in Linq to get result based on one field of the table (so do not require a whole duplicated records from table). I know writing basic query using distinct as followed: var query = (from r in table1 orderby r. Text select r).
It's annoying, certainly. It's also part of my "MoreLINQ" project which I must pay some attention to at some point :) There are plenty of other operations which make sense when acting on a projection, but returning the original - MaxBy and MinBy spring to mind.
As you say, it's easy to write - although I prefer the name "DistinctBy" to match OrderBy etc. Here's my implementation if you're interested:
public static IEnumerable<TSource> DistinctBy<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) { return source.DistinctBy(keySelector, EqualityComparer<TKey>.Default); } public static IEnumerable<TSource> DistinctBy<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer) { if (source == null) { throw new ArgumentNullException("source"); } if (keySelector == null) { throw new ArgumentNullException("keySelector"); } if (comparer == null) { throw new ArgumentNullException("comparer"); } return DistinctByImpl(source, keySelector, comparer); } private static IEnumerable<TSource> DistinctByImpl<TSource, TKey> (IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer) { HashSet<TKey> knownKeys = new HashSet<TKey>(comparer); foreach (TSource element in source) { if (knownKeys.Add(keySelector(element))) { yield return element; } } }
But that seems messy.
It's not messy, it's correct.
Distinct
Programmers by FirstName and there are four Amy's, which one do you want?Group
programmers By FirstName and take the First
one, then it is clear what you want to do in the case of four Amy's.I can only use it here because I have a single key.
You can do a multiple key "distinct" with the same pattern:
return myList .GroupBy( x => new { x.Url, x.Age } ) .Select( g => g.First() );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With