Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent to Javascript yield* in C# that delegates to another iterator?

Javascript has a yield* that is used to delegate to another generator or iterable object, such that the following use case produce 1 2 3 4 5 6 7 8 9:

for (const n of func1(2, 5, 8)) console.log(n)

function* func1(...nrs) {
    for (const n of nrs) {
        yield* func2(n)
    }
}

function* func2(nr) {
    yield nr - 1
    yield nr
    yield nr + 1
}

Question: Is there already, or any plan to provide an equivalent feature to yield* in C#?


The only way that I figure out to do something equivalent in C# requires two loops in func1 such as:

static void Main(string[] args)
{
    foreach(var n in func1(2, 5, 8)) Console.WriteLine(n);
}

static IEnumerable<int> func1(params int [] nrs) {
    foreach (var iter in nrs)
        foreach (var n in func2(iter))
            yield return n;
}
static IEnumerable<int> func2(int nr) {
    yield return nr - 1;
    yield return nr;
    yield return nr + 1;
}
like image 731
Miguel Gamboa Avatar asked Dec 20 '25 20:12

Miguel Gamboa


1 Answers

Whilst there is no equivalent to yield*, you could achieve the same in your example using Enumerable.SelectMany:

static IEnumerable<int> func1(params int[] nrs)
    => nrs.SelectMany(func2);

SelectMany also has deferred execution, as with yield.

Unfortunately, you couldn't combine this with another yield statement; you would need a foreach in that case:

static IEnumerable<int> func1(params int[] nrs)
{
    yield return 0; // Another yield
    foreach (var n in nrs.SelectMany(func2)) yield return n; // Loop now needed
}
like image 184
Johnathan Barclay Avatar answered Dec 23 '25 11:12

Johnathan Barclay



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!