I've two IEnumerable<double>
s, that I want to build an IEnumerable
of Tuple<int, double, double>
from. Item1
of the Tuple
should be the index of the item, Item2
the value in index-th place in the first collection, and Item3
the value in index-th place in the second collection. Is this something that can be done easily in Linq?
E.g.
var first = new List<double>() { 10.0, 20.0, 30.0 };
var second = new List<double>() { 1.0, 2.0, 3.0 };
var result = TupleBuild(first, second);
// result = {(0, 10.0, 1.0), (1, 20.0, 2.0), (2, 30.0, 3.0)}
where:
IEnumerable<Tuple<int, double, double>> TupleBuild(IEnumerable<double> first, IEnumerable<double> second)
{
// does some funky Linq
}
I realise I could write some longhand code for this, but I'd rather not reinvent the wheel if Linq has this covered.
All LINQ methods are extension methods to the IEnumerable<T> interface. That means that you can call any LINQ method on any object that implements IEnumerable<T> . You can even create your own classes that implement IEnumerable<T> , and those classes will instantly "inherit" all LINQ functionality!
The Tuple<T> class was introduced in . NET Framework 4.0. A tuple is a data structure that contains a sequence of elements of different data types. It can be used where you want to have a data structure to hold an object with properties, but you don't want to create a separate type for it.
IEnumerable in C# is an interface that defines one method, GetEnumerator which returns an IEnumerator interface. This allows readonly access to a collection then a collection that implements IEnumerable can be used with a for-each statement.
How about with the Zip
operator and the Select
overload that provides the index of the element:
return first.Zip(second, Tuple.Create)
.Select((twoTuple, index)
=> Tuple.Create(index, twoTuple.Item1, twoTuple.Item2));
By the way, you might as well then make the method generic:
IEnumerable<Tuple<int, TFirst, TSecond>> TupleBuild<TFirst, TSecond>
(IEnumerable<TFirst> first, IEnumerable<TSecond> second) { ... }
A more modern version updated per C# 7.0
(based on the answer of @Ani).
This uses the more readable (IMO) tuple syntax without Tuple.Create
. Also note the return type and the tuple deconstruction within the Select
method.
IEnumerable<(int, double, double)> TupleBuild
(IEnumerable<double> first, IEnumerable<double> second)
{
return first
.Zip(second)
.Select((tuple, index) =>
{
var (fst, snd) = tuple;
return (index, fst, snd);
});
}
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