Note that there are some explanatory texts on larger screens.

plurals
  1. PO"Lazy" GroupBy with Linq
    primarykey
    data
    text
    <p>I have recently been in a situation where I needed to perform an operation a grouped slowly yielding Linq query.</p> <p>Now, groupBy looses it's lazyness, that means that you have to wait for the entire Sequence to finish until you get any groups returned. This to me logically seems not the best solution, as a group can be returned as soon as it is first encountered.</p> <p>I have written the following code, which seems to work fine, and am looking for pitfalls and general improvements, as well as thoughts on the concept itself (eg. can/should a groupBy method return groups as soon as possible).</p> <pre><code>public static IEnumerable&lt;KeyValuePair&lt;R, IEnumerable&lt;T&gt;&gt;&gt; GroupByLazy&lt;T, R&gt;(this IEnumerable&lt;T&gt; source, Func&lt;T, R&gt; keySelector) { var dic = new Dictionary&lt;R, BlockingCollection&lt;T&gt;&gt;(); foreach (var item in source) { var Key = keySelector(item); BlockingCollection&lt;T&gt; i; if (!dic.TryGetValue(Key, out i)) { i = new BlockingCollection&lt;T&gt;(); i.Add(item); dic.Add(Key, i); yield return new KeyValuePair&lt;R, IEnumerable&lt;T&gt;&gt;(Key, i); } else i.TryAdd(item); } // mark all the groups as completed so that enumerations of group-items can finish foreach (var groupedValues in dic.Values) groupedValues.CompleteAdding(); } </code></pre> <p>Simple Test:</p> <pre><code>var slowIE = Observable.Interval(TimeSpan.FromSeconds(1)).ToEnumerable().Take(10); var debug = slowIE.Do(i =&gt; Console.WriteLine("\teval " + i)); var gl = debug.GroupByLazy(i =&gt; i % 2 == 0); var g = debug.GroupBy(i =&gt; i % 2 == 0); Console.WriteLine("Lazy:"); gl.Run(i =&gt; Console.WriteLine("Group returned: " + i.Key)); Console.WriteLine(gl.Single(i =&gt; i.Key).Value.Count()); Console.WriteLine("NonLazy:"); g.Run(i =&gt; Console.WriteLine("Group returned: " + i.Key)); Console.WriteLine(g.Single(i =&gt; i.Key).Count()); Console.ReadLine(); </code></pre> <p>which prints:</p> <pre><code>Lazy: eval 0 Group returned: True eval 1 Group returned: False eval 2 eval 3 eval 4 eval 5 eval 6 eval 7 eval 8 eval 9 NonLazy: eval 0 eval 1 eval 2 eval 3 eval 4 eval 5 eval 6 eval 7 eval 8 eval 9 Group returned: True Group returned: False </code></pre> <p>As you can see, in my LazyGroupBy the groups are returned as soon as they are first encountered, and can thus be acted upon without waiting for the entire sequence to be grouped.</p> <p>Thoughts?</p> <p>Edit: quick thought, I think "Lazy" is not the right term...I'm not a native speaker, what term am I actually looking for?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload