// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace System.Linq
{
public static partial class EnumerableEx
{
///
/// Generates an enumerable sequence by repeating a source sequence as long as the given loop condition holds.
///
/// Result sequence element type.
/// Loop condition.
/// Sequence to repeat while the condition evaluates true.
/// Sequence generated by repeating the given sequence while the condition evaluates to true.
public static IEnumerable While(Func condition, IEnumerable source)
{
if (condition == null)
throw new ArgumentNullException("condition");
if (source == null)
throw new ArgumentNullException("source");
return WhileCore(condition, source).Concat();
}
static IEnumerable> WhileCore(Func condition, IEnumerable source)
{
while (condition())
yield return source;
}
///
/// Returns an enumerable sequence based on the evaluation result of the given condition.
///
/// Result sequence element type.
/// Condition to evaluate.
/// Sequence to return in case the condition evaluates true.
/// Sequence to return in case the condition evaluates false.
/// Either of the two input sequences based on the result of evaluating the condition.
public static IEnumerable If(Func condition, IEnumerable thenSource, IEnumerable elseSource)
{
if (condition == null)
throw new ArgumentNullException("condition");
if (thenSource == null)
throw new ArgumentNullException("thenSource");
if (elseSource == null)
throw new ArgumentNullException("elseSource");
return EnumerableEx.Defer(() => condition() ? thenSource : elseSource);
}
///
/// Returns an enumerable sequence if the evaluation result of the given condition is true, otherwise returns an empty sequence.
///
/// Result sequence element type.
/// Condition to evaluate.
/// Sequence to return in case the condition evaluates true.
/// The given input sequence if the condition evaluates true; otherwise, an empty sequence.
public static IEnumerable If(Func condition, IEnumerable thenSource)
{
if (condition == null)
throw new ArgumentNullException("condition");
if (thenSource == null)
throw new ArgumentNullException("thenSource");
return EnumerableEx.Defer(() => condition() ? thenSource : Enumerable.Empty());
}
///
/// Generates an enumerable sequence by repeating a source sequence as long as the given loop postcondition holds.
///
/// Result sequence element type.
/// Source sequence to repeat while the condition evaluates true.
/// Loop condition.
/// Sequence generated by repeating the given sequence until the condition evaluates to false.
public static IEnumerable DoWhile(this IEnumerable source, Func condition)
{
if (source == null)
throw new ArgumentNullException("source");
if (condition == null)
throw new ArgumentNullException("condition");
return source.Concat(While(condition, source));
}
///
/// Returns a sequence from a dictionary based on the result of evaluating a selector function.
///
/// Type of the selector value.
/// Result sequence element type.
/// Selector function used to pick a sequence from the given sources.
/// Dictionary mapping selector values onto resulting sequences.
/// The source sequence corresponding with the evaluated selector value; otherwise, an empty sequence.
public static IEnumerable Case(Func selector, IDictionary> sources)
{
if (selector == null)
throw new ArgumentNullException("selector");
if (sources == null)
throw new ArgumentNullException("sources");
return Case(selector, sources, Enumerable.Empty());
}
///
/// Returns a sequence from a dictionary based on the result of evaluating a selector function, also specifying a default sequence.
///
/// Type of the selector value.
/// Result sequence element type.
/// Selector function used to pick a sequence from the given sources.
/// Dictionary mapping selector values onto resulting sequences.
/// Default sequence to return in case there's no corresponding source for the computed selector value.
/// The source sequence corresponding with the evaluated selector value; otherwise, the default source.
public static IEnumerable Case(Func selector, IDictionary> sources, IEnumerable defaultSource)
{
if (selector == null)
throw new ArgumentNullException("selector");
if (sources == null)
throw new ArgumentNullException("sources");
if (defaultSource == null)
throw new ArgumentNullException("defaultSource");
return EnumerableEx.Defer(() =>
{
IEnumerable result;
if (!sources.TryGetValue(selector(), out result))
result = defaultSource;
return result;
});
}
///
/// Generates a sequence by enumerating a source sequence, mapping its elements on result sequences, and concatenating those sequences.
///
/// Source sequence element type.
/// Result sequence element type.
/// Source sequence.
/// Result selector to evaluate for each iteration over the source.
/// Sequence concatenating the inner sequences that result from evaluating the result selector on elements from the source.
public static IEnumerable For(IEnumerable source, Func> resultSelector)
{
if (source == null)
throw new ArgumentNullException("source");
if (resultSelector == null)
throw new ArgumentNullException("resultSelector");
return ForCore(source, resultSelector).Concat();
}
static IEnumerable> ForCore(IEnumerable source, Func> resultSelector)
{
return source.Select(resultSelector);
}
}
}