Click here to Skip to main content
Licence CPOL
First Posted 5 Jan 2012
Views 6,866
Bookmarked 10 times

A 'Between' extension method for LINQ in C#.

By | 5 Jan 2012 | Technical Blog
Here's an example of a simple LINQ extension method for getting values that fall within a certain range from an IEnumerable collection.
A Technical Blog article. View original blog here.[^]

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.

Picture: Linq Between Extension Method

/// <summary>
/// Returns the values in a sequence whose resulting value of the specified 
/// selector is between the lowest and highest values given in the parameters.
/// </summary>
/// <typeparam name="TSource">
/// The type of elements in the sequence.
/// </typeparam>
/// <param name="source">
/// The IEnumerable object on which this method works.
/// </param>
/// <param name="selector">
/// The selector predicate used to attain the value.
/// </param>
/// <param name="lowest">
/// The lowest value of the selector that will appear in the new list.
/// </param>
/// <param name="highest">
/// The hightest value of the selector that will appear in the new list.
/// </param>
/// <returns>
/// An IEnumerable sequence of TSource whose selector values fall within the range 
/// of <paramref name="lowest"/> and <paramref name="highest"/>.
/// </returns>
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 );
}
 
/// <summary>
/// This is a simple test for the Between Linq extension method. We'll add a few
/// values to a list and select only those that are between a certain range.
/// When we're done, we should know the lowest and highest values contained
/// in the resulting values set.
/// </summary>
[TestMethod]
public void BetweenTest()
{
    var list = <a href="http://www.google.com/search?q=new+msdn.microsoft.com">new</a> 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);
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

qenn

Engineer

United States United States

Member

Follow on Twitter Follow on Twitter


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Question[My vote of 2] Binary Search Pinmemberfrblondin23:03 6 Jan '12  
QuestionNo need to require OrderBy... PinmemberMatt T Heffron13:53 6 Jan '12  
SuggestionOff Topic - UserID Pinmvpthatraja1:46 6 Jan '12  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 5 Jan 2012
Article Copyright 2012 by qenn
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid