In JavaScript ES6, you are able to destructure arrays like this:
const [a,b,...rest] = someArray;
where a
is the first element in the array, b
is the second, and rest
is an array with the remaining elements.
I know in C#7 that you can destructure tuples during assignment, but could not find anything related to destructuring arrays/enumerables like this:
var (a,b) = someTuple;
I have an IEnumerable
where I need the first and second elements as variables, and I need the rest of the elements as another IEnumerable. I have a solution, but feel that destructuring will look cleaner.
The do-while statement lets you repeat a statement or compound statement until a specified expression becomes false.
The ' |= ' symbol is the bitwise OR assignment operator.
It turns out not only tuples can be deconstructed but any type which has Deconstruct
static (or extension) method with matching signature. Doing deconstruction correctly for IEnumerable
is not trivial (see library suggested by David Arno in this answer), so let's see how it works with simple IList
instead (implementation is irrelevant, this one is for example and of course can be better/different):
public static class Extensions { public static void Deconstruct<T>(this IList<T> list, out T first, out IList<T> rest) { first = list.Count > 0 ? list[0] : default(T); // or throw rest = list.Skip(1).ToList(); } public static void Deconstruct<T>(this IList<T> list, out T first, out T second, out IList<T> rest) { first = list.Count > 0 ? list[0] : default(T); // or throw second = list.Count > 1 ? list[1] : default(T); // or throw rest = list.Skip(2).ToList(); } }
Then (after adding relevant using statements if necessary) you can use exactly the syntax you want:
var list = new [] {1,2,3,4}; var (a,rest) = list; var (b,c,rest2) = list;
Or you can chain deconstruction like this (because last returned value can itself be deconstructed):
var (a, (b, (c, rest))) = list;
With last version, you can deconstruct to any number of items using single Deconstruct
method (that one which returns first item and the rest).
For real usage for IEnumerables, I'd suggest to not reimplement the wheel and use David Arno's library mentioned in this answer.
What you are describing is generally known in functional languages as "cons", which often takes the form:
let head :: tail = someCollection
I did propose this be added to C#, but it didn't receive very favourable feedback. So I wrote my own, which you can use via the Succinc<T> nuget package.
It uses deconstruction to achieve that splitting of the head and tail of any IEnumerable<T>
. Deconstructs can be nested, so you can use it to extract multiple elements in one go:
var (a, (b, rest)) = someArray;
This potentially could provide the functionality you are after.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With