The Standard Query Operators are great, but at the same time there are ones I'm missing.
They are not hard to implement oneself, but maybe they are worth including in standard set.
1. By
public static IEnumerable<IEnumerable<T>> By<T>(this IEnumerable<T> source, int count); |
By operator groups the elements of a sequence by count.
This code would return lists of products 10 products in each:
var productPages = products.By(10); |
sequence.By(count) should be semantically identical to:
sequence.Select((elem, index) => new {Elem = elem, Index = index / count}).GroupBy(e => e.Index, e => e.Elem).Select(g => g.Group) |
2. Shuffle
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source); public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random random); |
Shuffle operator randomly shuffles a sequence.
This code would return 3 randomly chosen product:
var productBanners = products.Shuffle().Take(3); |
sequence.Shuffle(random) should be semantically identical to:
sequence.Select(elem => new {Elem = elem, Tag = random.NextDouble()}).OrderBy(e => e.Tag).Select(e => e.Elem) |

More Standard Query Operators
HK.Lee
Skip() and Take() are implementation details. It is very conceivable (if not already the case) that a particular DB implements paging support directly in its query language, in which case it's probably better (and potentially easier) to specify the page number and page size directly, rather than infer that Skip() followed by Take() are intended to refer to paging. In fact, Skip(n).Take(m) can only be translated to a page operation iff (n/m) is integer.
Just got back from the Launch in SF. Looong day..
guysky
Ravimcom
However, what would this code do:
var productPages = products.By(10);
return productPages.ToArray();
Would the ToArray() just return an array of 10 or the complete list How would you get the next 10 items
spert
>By operator groups the elements of a sequence by count.
Not sure how this would vary from using a having where the index value is divided by N.
>Shuffle operator randomly shuffles a sequence.
So the use case for that is...
Also, I don't think I want the internal store shuffled (consider the primacy of document order in XML) first and then just pop the top 3. If the semantic were (randomly select N indexes and construct a new sequence of values), it'd be better. Chaotic, but better.
Ed Pinto - MSFT
I believe that the Skip and Take extension methods provide this.
From the Standard Query Operators doc:
So a sequence.Skip(10).Take(10) would yield the ten items of the second page if the page size was ten. sequence.Skip(20).Take(10) would yield the third page, etc.
Manish_Jain
There’s a tipping point where too much declarative syntax obfuscates the intent of the API in favor of trivial pursuits in natural language programming. There’s only so much black box stuff that we should do and expect before black box pursuits have a degenerative effect on sustainability.
I personally don’t know if a PageBy() extension method is beyond that tipping point, but it seems closer to the tipping point than the use of existing extension methods that seeminigly provide the same capabilities with different syntax.
If I can achieve PageBy() with the existing Skip() and Take() extension methods, then PageBy() starts to smell like keyword and API bloat.
Is the PageBy() thing simply an alternate syntax for Skip().Take(), or is it something entirely new
dX10
shart44
>Not sure how this would vary from using a having where the index value is divided by N.
Well...
1. It shorter and much more readable than Select->GroupBy->Select, and it's convenient to use.
2. By operator can be implemented in a lazy load way, whereas GroupBy in general case cannot.
public static IEnumerable<IEnumerable<T>> By<T>(this IEnumerable<T> source, int count)
{
List<T> list = new List<T>(count);
foreach (T elem in source)
{
list.Add(elem);
if (list.Count == count)
{
yield return list;
list = new List<T>(count);
}
}
if (list.Count > 0)
yield return list;
}
>>Shuffle operator randomly shuffles a sequence.
>So the use case for that is...
Any, where you need a collection iterated in the random order. Advertising, computer games, testing, load balancing, etc.
>Also, I don't think I want the internal store shuffled (consider the primacy of
>document order in XML) first and then just pop the top 3. If the semantic were
>(randomly select N indexes and construct a new sequence of values), it'd be
>better. Chaotic, but better.
That may be my fault the meaning of Shuffle operator wasn't clear. Intended sematics was to iterate a sequence in random order, not to shuffle the source collection.
EricEarle
At some intermediate point, I think you'd need to group by the pages, and then access the page.
var productPages = products.PageBy(10);
Console.WriteLine("Page 3: {0} products", productPages[2].ToArray());
2)
foreach (Page<Product> page in productPages)
{
Console.WriteLine("Page {0}: {1} products, element indices {2} through {3}",
page.PageNumber, // == page.Index + 1
page.Count,
page.MinIndex,
page.MaxIndex
}
3)
var pageN =
from p in products
page size 10
page index n // dunno about the syntax...
Noam