"the classy way to filter collections"
This library allows an IEnumerable to be filtered using either a typed or anonymous class.
Install the RimDev.Filter NuGet package.
Install-Package RimDev.Filter
using RimDev.Filter.Generic;
using RimDev.Filter.Range;
public class Person
{
public Person(string firstName, int favoriteNumber)
{
FavoriteNumber = favoriteNumber;
FirstName = firstName;
}
public int FavoriteNumber { get; set; }
public string FirstName { get; set; }
}
var people = new List<Person>()
{
new Person("John", 1),
new Person("Tom", 2),
new Person("Jane", 3),
new Person("Sally", 4)
};
IEnumerable<Person> filteredPeople = null;
// returns just the first-record.
filteredPeople = people.Filter(new
{
FirstName = "John"
});
// returns the first and second-record.
filteredPeople = people.Filter(new
{
FirstName = new[] { "John", "Tom" }
});
// returns the second-record.
filteredPeople = people.Filter(new
{
FavoriteNumber = Range.FromString<int>("(1,3)")
});
// returns the first three-records.
filteredPeople = people.Filter(new
{
FavoriteNumber = Range.FromString<int>("[1,4)")
});
This is a new type which allows an easy way to represent a range of values when filtering. An instance can either be created manually or via a helper which takes a string formatted using standard interval notation.
While any type is allowed as a range, only certain types will work when filtering:
- byte
- char
- DateTime
- DateTimeOffset
- decimal
- double
- float
- int
- long
- sbyte
- short
- uint
- ulong
- ushort
Any other types will just silently get passed-over.
using RimDev.Filter.Range;
using RimDev.Filter.Range.Generic;
var range = new Range<int>()
{
MinValue = 0,
MaxValue = 10,
IsMinInclusive = false,
IsMaxInclusive = true
};
// or with helper.
var range = Range.FromString<int>("(0,10]");
Instead of having to call the static-helper Range.FromString<T>
, you can also leverage implicit casting support:
Range<int> range = "[1,5]";
// or...
// Type is Range<int>.
var range2 = (Range<int>)"[1,5]";
Instead of having to specify both lower and upper-bound, you can truncate one of the two:
// x <= 5
var range = (Range<int>)"(,5]";
// range.MinValue.HasValue == false;
// or use Unicode
var range2 = (Range<int>)"(-∞,5]";
var range3 = (Range<int>)"[1,+∞)";
Some assumptions are made if enclosing-characters (i.e. [
, (
, ]
, )
) are not used:
var range = (Range<int>)"123";
// range.MinValue == 123;
// range.MaxValue == 123;
// range.IsMinInclusive == true;
// range.IsMaxInclusive == true;
var range2 = (Range<int>)",456";
// range2.MinValue == null;
// range2.MaxValue == 456;
// range2.IsMinInclusive == true;
// range2.IsMaxInclusive == true;
var range3 = (Range<int>)"(123,";
// range3.MinValue == 123;
// range3.MaxValue == 123;
// range3.IsMinInclusive == false;
// range3.IsMaxInclusive == true;
- The library currently only works with class-type collections.
- Constant filter-value (i.e. non-enumerable or range) exceptions are trapped within the
Filter
call.
Issue documentation and pull-requests are welcomed. This project follows the fork & pull model.