Here's an example of a simple LINQ extension method for getting values that fall within a certain range from an IEnumerable
collection. First, we order the TSource
items using the given selector. Then, we use Invoke
on each item in the collection to determine if the selector's result is above the lowest value we want. If it isn't, we skip it with the SkipWhile
method. Once we're at a point where we know the selector's result is at least as large as the lowest value we want, we start taking items with the TakeWhile
method until the same Invoke
returns a value larger than the largest item we want. Then, we just stop and return. It's a one-liner.
public static IEnumerable<TSource> Between<TSource, TResult>
(
this IEnumerable<TSource> source, Func<TSource, TResult> selector,
TResult lowest, TResult highest
)
where TResult : IComparable<TResult>
{
return source.OrderBy(selector).
SkipWhile(s => selector.Invoke(s).CompareTo(lowest) < 0).
TakeWhile(s => selector.Invoke(s).CompareTo(highest) <= 0 );
}
[TestMethod]
public void BetweenTest()
{
var list = new List<double>();
for (var i = 1; i <= 20; i++)
list.Add(i);
var fiveTo15 = list.Between(s => s, 5, 15);
Assert.IsTrue(fiveTo15.Min() == 5);
Assert.IsTrue(fiveTo15.Max() == 15);
}