Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ merge List<IEnumerable<T>> into one IEnumerable<T> by some rule

Tags:

c#

linq

Lets say I have a List<IEnumerable<double>> containing variable number of infinite sources of double numbers. Lets say they are all wave generator functions and I need to superimpose them into a single wave generator represented by IEnumerable<double> simply by taking the next number out of each and suming them.

I know I can do this through iterator methods, something like this:

    public IEnumerable<double> Generator(List<IEnumerable<double>> wfuncs)
    {
        var funcs = from wfunc in wfuncs
                    select wfunc.GetEnumerator();

        while(true)
        {
            yield return funcs.Sum(s => s.Current);
            foreach (var i in funcs) i.MoveNext();
        }
    } 

however, it seems rather "pedestrian". Is there a LINQ-ish way to achieve this?

like image 369
mmix Avatar asked Nov 09 '15 12:11

mmix


1 Answers

You could aggregate the Zip-method over the IEnumerables.

    public IEnumerable<double> Generator(List<IEnumerable<double>> wfuncs)
    {
        return wfuncs.Aggregate((func, next) => func.Zip(next, (d, dnext) => d + dnext));
    }

What this does is bascically applies the same Zip-method over and over again. With four IEnumerables this would expand to:

wfuncs[0].Zip(wfuncs[1], (d, dnext) => d + dnext)
         .Zip(wfuncs[2], (d, dnext) => d + dnext)
         .Zip(wfuncs[3], (d, dnext) => d + dnext);

Try it out: fiddle

like image 132
frich Avatar answered Mar 16 '23 18:03

frich