I Want a “while” Linq Keyword
The other day when I was playing with the coin change code kata, I thought I’d try doing it in the keyword-based “sql” style of linq coding. The hurdle I struck (well, not the only hurdle, but a major one) is that not all of the linq extension methods have keyword equivalents. Case in point, the TakeWhile() extension method.
What I’d like to see in a future version of C# is for the team to hijack the existing “while” keyword and let us use that. So the code would become:
var solution = from c in coins orderby c descending while amount > 0 select new { Coin = c, Number = amount / c, Remainder = (amount %= c) };
Now, this is missing the final “Where” clause from the previous posts (which filters out any coins that don’t apply), but that’s no big deal.
I’m not sure why the C# team didn’t include the “while” keyword in their longhand linq syntax from the get-go. Perhaps it was difficult to parse, or maybe they were concerned about making a query that “looks” set based use an iterative keyword like that. I think it fits right in! How about you?
Comments
# BitBotDev
5/02/2010 2:47 AM
I wrote a While extension method for a projetc i was on to do what you were asking for. For those interested-
/// <summary>
/// Calls .While(collection, condition, operation , true)-
/// will repeat the opearation until the condition is true.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection">The collection.</param>
/// <param name="condition">The condition.</param>
/// <param name="operation">The operation.</param>
public static void While<T>(this IEnumerable<T> collection, Predicate<T> condition, Action<T> operation)
{
collection.While(condition, operation, true);
}
/// <summary>
/// iterates over the specified collection while condition = true;
/// applies operation to each item in the collection.
/// if repeatUntilConditionMet = true, enumerator will reset at end of loop until condition is met
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection">The collection.</param>
/// <param name="condition">The condition.</param>
/// <param name="operation">The operation.</param>
/// <param name="repeatUntilConditionMet">if set to <c>true</c> [repeat until condition met].</param>
public static void While<T>(this IEnumerable<T> collection, Predicate<T> condition, Action<T> operation, bool repeatUntilConditionMet)
{
IEnumerator<T> enumerator;
if (collection != null)
{
enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
if (condition.Invoke(enumerator.Current))
{
operation.Invoke(enumerator.Current);
if (enumerator.Current.Equals(collection.LastOrDefault()) && repeatUntilConditionMet)
{
enumerator.Reset();
}
}
else
{
break;
}
}
}
}