Everything in LINQ
is by design meant to never modify the underlying collection and to always create a new enumeration that is generally then used to instantiate a new collection.
You can write a helper function like this to achieve what you want:
public static void SelectToDestination<TSource, TResult>(
Func<TSource, TResult> selector,
IEnumerable<TSource> source,
IList<TResult> destination)
{
int i = 0;
foreach (var item in source.Select(selector))
{
destination[i] = item;
i++;
}
}
Usage looks like this:
var l1 = new List<int>() { 1, 2, 3, 4 };
var l2 = new List<int>() { 0, 0, 0, 0 };
SelectToDestination(x => x + 2, l1, l2);
foreach(var item in l2)
{
Console.Write(item + " ");
}
Results in: 3 4 5 6
Since we're using IList<T>
in the method's signature, the destination can be an array too and it will work fine:
public static void Main(string[] args)
{
var l1 = new List<int>() { 1, 2, 3, 4 };
var l2 = new int[4];
SelectToDestination(x => x + 2, l1, l2);
foreach(var item in l2)
{
Console.Write(item + " ");
}
}
It takes advantage of the fact that until you call something like ToArray()
or ToList()
, LINQ hasn't yet instantiated a new collection, it's just iterating lazily over elements in the source collection. So just don't call ToArray()
or ToList()
, iterate over the resulting IEnumerable<TResult>
and assign it to destination. Note that there are probably more perf friendly ways of doing this if that's a concern for you.
Just like Julia's map method, this will only work if the destination collection is at least as big.