I'm doing a C# exercise to create an operation that takes a collection, performs a function on each object in the collection, and returns a collection of modified objects.
My code is currently as follows:
public static IEnumerable<U> Accumulate<T, U>(this IEnumerable<T> collection, Func<T, U> func)
{
IEnumerable<U> output = Enumerable.Empty<U>();
foreach (T item in collection)
{
output.Append(func(item));
}
return output;
}
This is only returning an empty collection, and I have no idea why.
I have tried creating a copy of the item in the foreach after seeing this approach in another thread, like so:
foreach (T item in collection)
{
U copy = func(item);
output.Append(copy);
}
but that didn't solve anything.
I did some research but couldn't really find any examples doing exactly what I'm trying to do here. I read some things about closure, but couldn't really understand it, as I'm new to C#.
To answer your actual question: The reason it isn't working is because
output.Append(func(item));
doesn't change output
- instead, it returns a new sequence which is func(item)
appended to output
. Thus when you eventually return output
you are just returning the original, empty sequence.
You could make yours work by this simple change:
output = output.Append(func(item));
However, this is not an efficient approach - you're much better off using yield
, by modifying your method as follows:
public static IEnumerable<U> Accumulate<T, U>(this IEnumerable<T> collection, Func<T, U> func)
{
foreach (T item in collection)
{
yield return func(item);
}
}
Although note that that is more simply expressed as:
public static IEnumerable<U> Accumulate<T, U>(this IEnumerable<T> collection, Func<T, U> func)
{
return collection.Select(item => func(item));
}
But it is useful to know about how to do this with yield
so that you can write solutions to more complex Linq-like problems.
Usually, when I want to achieve this kind of behaviour, I make use of C# Iterators. They are so usefull when you want to process an iteration on some kind of data and, at each iteration, return a value that is appended to your resulting collection.
Take a look at the docs: MS Docs
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