ExtraLINQ provides a set of extension methods for various .NET sequence types.
ExtraLINQ is available as a NuGet package:
Install-Package ExtraLINQ
Extensions for collections of type IEnumerable<T>
:
Chunk
Cycle
Distinct
Each
Flatten
HasExactly
HasAtMost
HasAtLeast
Intersperse
IsEmpty
IsNullOrEmpty
JoinedBy
None
Partition
Random
Repeat
Shuffle
TakeSkip
ToHashSet
WhereNot
Without
Extensions for collections of type NameValueCollection
:
Splits the given sequence into chunks of the given size. If the sequence length isn't evenly divisible by the chunk size, the last chunk will contain all remaining elements.
int[] numbers = { 1, 2, 3, 4, 5, 6, 7 };
int[][] chunks = numbers.Chunk(3).ToArray();
// chunks = [[1, 2, 3], [4, 5, 6], [7]]
Turns a finite sequence into a circular one, or equivalently, repeats the original sequence indefinitely.
int[] bits = { 0, 1 };
int[] alternatingBits = bits.Cycle().Take(5).ToArray();
// alternatingBits = [0, 1, 0, 1, 0]
Returns distinct elements from the given sequence using the default equality comparer to compare projected values.
string[] spellingsOfJavaScript = { "JavaScript", "Javascript", "javascript" };
string[] distinctSpellings = spellingsOfJavaScript
.Distinct(n => n.ToLower())
.ToArray();
// distinctSpellings = ["JavaScript"]
Passes every element of the sequence to the specified action and returns it afterwards.
string[] ringInscriptionLines =
{
"One Ring to rule them all",
"One Ring to find them",
"One Ring to bring them all",
"and in the darkness bind them"
};
ringInscriptionLines.Each(Console.WriteLine);
// Console output:
//
// One Ring to rule them all
// One Ring to find them
// One Ring to bring them all
// and in the darkness bind them
Returns a flattened sequence that contains the concatenation of all the nested sequences' elements.
int[][] numbers =
{
new[] { 1, 2, 3 },
new[] { 4, 5 },
new[] { 6 }
};
int[] flattenedNumbers = numbers.Flatten().ToArray();
// flattenedNumbers = [1, 2, 3, 4, 5, 6]
Determines whether a collection contains at least a certain number of items.
string[] theThreeRings = { "Narya", "Nenya", "Vilya" };
theThreeRings.HasAtLeast(0) // true
theThreeRings.HasAtLeast(2) // true
theThreeRings.HasAtLeast(4) // false
Optionally, a predicate can be passed that is called for every element:
string[] theThreeRings = { "Narya", "Nenya", "Vilya" };
theThreeRings.HasAtLeast(2, ring => ring.StartsWith("N")) // true
theThreeRings.HasAtLeast(3, ring => ring.StartsWith("N")) // false
Determines whether a collection contains at most a certain number of items.
string[] theThreeRings = { "Narya", "Nenya", "Vilya" };
theThreeRings.HasAtMost(2) // false
theThreeRings.HasAtMost(3) // true
theThreeRings.HasAtMost(4) // true
Optionally, a predicate can be passed that is called for every element:
string[] theThreeRings = { "Narya", "Nenya", "Vilya" };
theThreeRings.HasAtMost(1, ring => ring.StartsWith("N")) // false
theThreeRings.HasAtMost(2, ring => ring.StartsWith("N")) // true
Determines whether a collection contains exactly a given number of items.
string[] theThreeRings = { "Narya", "Nenya", "Vilya" };
theThreeRings.HasExactly(2) // false
theThreeRings.HasExactly(3) // true
theThreeRings.HasExactly(4) // false
Optionally, a predicate can be passed that is called for every element:
string[] theThreeRings = { "Narya", "Nenya", "Vilya" };
theThreeRings.HasExactly(1, ring => ring.StartsWith("N")) // false
theThreeRings.HasExactly(1, ring => ring.StartsWith("V")) // true
theThreeRings.HasExactly(2, ring => ring.StartsWith("N")) // true
Returns all elements of the collection separated by the given separator.
int[] numbers = { 1, 2, 3, 4, 5 };
int[] separatedNumbers = numbers.Intersperse(0).ToArray();
// separatedNumbers = [1, 0, 2, 0, 3, 0, 4, 0, 5]
Determines whether a collection is empty.
new int[0].IsEmpty() // true
new[] { 1, 2, 3 }.IsEmpty() // false
Determines whether a collection is null or empty.
(null as int[]).IsNullOrEmpty() // true
new int[0].IsNullOrEmpty() // true
new[] { 1, 2, 3 }.IsNullOrEmpty() // false
Concatenates all items of a sequence using the specified separator between each item.
string[] nameParts = { "The", "One", "Ring" };
string ringName = nameParts
.Select(part => part.ToUpper())
.JoinedBy(" ");
// ringName = "THE ONE RING"
Note that the main purpose of JoinedBy
is to provide a chainable wrapper around String.Join
.
Determines whether a collection doesn't contain any elements matching certain criteria.
string[] theThreeRings = { "Narya", "Nenya", "Vilya" };
bool allRingsNamed = theThreeRings.None(string.IsNullOrWhiteSpace);
// allRingsNamed = true
The None
method is equivalent to a negated version of Any
.
Uses the given predicate to partition the given sequence into two sequences, one with all the matches and one with all the mismatches.
int[] numbers = { 1, 2, 3, 4, 5 };
var partitionedNumbers = numbers.Partition(n => n % 2 == 0);
// partitionedNumbers.Matches = [2, 4]
// partitionedNumbers.Mismatches = [1, 3, 5]
Returns a given number of random elements from a collection.
int[] numbers = Enumerable.Range(1, 49).ToArray();
int[] lottoNumbers = numbers
.Random(6)
.OrderBy(n => n)
.ToArray();
// e.g. lottoNumbers = [5, 19, 20, 27, 38, 41]
Repeats a given sequence a given number of times.
string[] eatingSounds = { "om", "nom", "nom" };
string[] cookieMonsterSounds = eatingSounds.Repeat(3).JoinedBy(" ");
// cookieMonsterSounds = ["om", "nom", "nom", "om", "nom", "nom", "om", "nom", "nom"]
Enumerates the specified input sequence and returns a new sequence which contains all input elements in random order.
string[] hobbits = { "Frodo", "Sam", "Merry", "Pippin" };
string[] shuffledHobbits = hobbits.Shuffle().ToArray();
// e.g. shuffledHobbits = ["Sam", "Pippin", "Frodo", "Merry"]
Iterates over the given sequence and repeatedly returns a specified number of elements before skipping a specified number of elements.
string[] fellowship =
{
"Frodo",
"Sam",
"Merry",
"Pippin",
"Aragorn",
"Legolas",
"Gimli",
"Boromir",
"Gandalf"
};
string[] everyOtherFellow = fellowship.TakeSkip(1, 1).ToArray();
// everyOtherFellow = ["Frodo", "Merry", "Aragorn", "Gimli", "Gandalf"]
Creates a HashSet
from a given sequence.
string gollumsUtterings = "Nasty hobbitses, gollum, gollum!";
HashSet<string> gollumsVocabulary = gollumsUtterings
.Split(new[] { ' ', ',', '!' }, StringSplitOptions.RemoveEmptyEntries)
.ToHashSet();
// gollumsVocabulary = ["Nasty", "hobbitses", "gollum"]
Note that the main purpose of ToHashSet
is to provide a chainable wrapper around the HashSet
constructor.
Filters a sequence of values based on a given predicate and returns those values that don't match the predicate.
string[] theThreeRings = { "Narya", "Nenya", "Vilya" };
Func<string, bool> startsWithN = value => value.StartsWith("N");
string vilya = theThreeRings.WhereNot(startsWithN).Single();
// vilya = "Vilya"
Returns the specified collection without the specified items.
string[] hobbits = { "Frodo", "Sam", "Merry", "Pippin" };
string[] mainHobbits = hobbits.Without("Merry", "Pippin").ToArray();
// mainHobbits = ["Frodo", "Sam"]
Returns a new dictionary from the specified collection.
var ringBearers = new NameValueCollection
{
{ "Nenya", "Galadriel" },
{ "Narya", "Gandalf" },
{ "Vilya", "Elrond" }
};
Dictionary<string, string> ringBearersDictionary = ringBearers.ToDictionary();
Enumerates the specified collection as a sequence of key-value pairs.
var ringBearers = new NameValueCollection
{
{ "Nenya", "Galadriel" },
{ "Narya", "Gandalf" },
{ "Vilya", "Elrond" }
};
IEnumerable<KeyValuePair<string, string>> ringBearersKeyValuePairs = ringBearers.ToKeyValuePairs();