Reputation: 224089
I have a function f()
and an IEnumerable<string>
from which I want to create another IEnumerable<string>
so that for each string s
in the original enumeration the new one has s
and f(s)
. The order of elements is important.
Example:
IEnumerable<string> given = { "A", "B", "C" };
IEnumerable<string> wanted = { "A", f("A"), "B", f("B"), "C", f("C") };
Is there a way to do this elegantly using LINQ? (And if not, what's the most elegant way to do this?)
Upvotes: 4
Views: 199
Reputation: 27608
What about something like this:
public static IEnumerable<string> AddFuncCall(this IEnumerable<string> input)
{
foreach (string s in input)
{
yield return s;
yield return "f(" + s + ")";
}
}
If you need the quotes embedded in the strings, try this (not 100% sure on syntax):
public static IEnumerable<string> AddFuncCall(this IEnumerable<string> input)
{
foreach (string s in input)
{
yield return @""" + s + @""";
yield return @"f("" + s + @"")";
}
}
IEnumerable<string> given = { "A", "B", "C"};
IEnumerable<string> wanted = given.AddFuncCall();
[EDIT]
Sorry, I misread the question, I thought you wanted strings like "f("A")" in the output as opposed to executing f
on each string from the input. Whoops!
Upvotes: 1
Reputation: 113412
var wanted = given.SelectMany(s => new[] {s, f(s)} );
Enumerable.SelectMany
projects each element of a sequence to another sequence and then flattens the resulting sequence of sequences into a single sequence.
In query syntax:
var wanted = from s in given
from item in new[] {s, f(s)}
select item;
Another alternative (if ordering were not important):
var wanted = given.Concat(given.Select(f)); // C# 4
var wanted = given.Concat(given.Select(s => f(s))); // C# 3
Upvotes: 8