.ToLookup<TSource, TKey>
returns an ILookup<TKey, TSource>
. ILookup<TKey, TSource>
also implements interface IEnumerable<IGrouping<TKey, TSource>>
.
.GroupBy<TSource, TKey>
returns an IEnumerable<IGrouping<Tkey, TSource>>
.
ILookup has the handy indexer property, so it can be used in a dictionary-like (or lookup-like) manner, whereas GroupBy can't. GroupBy without the indexer is a pain to work with; pretty much the only way you can then reference the return object is by looping through it (or using another LINQ-extension method). In other words, any case that GroupBy works, ToLookup will work as well.
All this leaves me with the question why would I ever bother with GroupBy? Why should it exist?
GroupBy() Method in C# The GroupBy() is an extension method that returns a group of elements from the given collection based on some key value. arr. GroupBy(b => chkSmaller(b)); The above chkSmaller() finds the elements smaller than 50.
ToLookup operator in LINQ is an extension method, and it is used to extract a set of key/value pairs from the source. Here, each element in the resultant collection is a generic Lookup object. Lookup object holds the Key and subsequence items that matched with the Key.
why would I ever bother with GroupBy? Why should it exist?
What happens when you call ToLookup on an object representing a remote database table with a billion rows in it?
The billion rows are sent over the wire, and you build the lookup table locally.
What happens when you call GroupBy on such an object?
A query object is built; end of story.
When that query object is enumerated then the analysis of the table is done on the database server and the grouped results are sent back on demand a few at a time.
Logically they are the same thing but the performance implications of each are completely different. Calling ToLookup means I want a cache of the entire thing right now organized by group. Calling GroupBy means "I am building an object to represent the question 'what would these things look like if I organized them by group?'"
In simple LINQ-world words:
ToLookup()
- immediate executionGroupBy()
- deferred executionThe two are similar, but are used in different scenarios. .ToLookup()
returns a ready to use object that already has all the groups (but not the group's content) eagerly loaded. On the other hand, .GroupBy()
returns a lazy loaded sequence of groups.
Different LINQ providers may have different behaviors for the eager and lazy loading of the groups. With LINQ-to-Object it probably makes little difference, but with LINQ-to-SQL (or LINQ-to-EF, etc.), the grouping operation is performed on the database server rather than the client, and so you may want to do an additional filtering on the group key (which generates a HAVING
clause) and then only get some of the groups instead of all of them. .ToLookup()
wouldn't allow for such semantics since all items are eagerly grouped.
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