[ACCEPTED]-Linq Aggregate complex types into a string-string-concatenation

Accepted answer
Score: 57

You have two options:

  1. Project to a string and then 8 aggregate:

    var values = new[] {
        new { Key = "MyAge", Value = 33.0 },
        new { Key = "MyHeight", Value = 1.75 },
        new { Key = "MyWeight", Value = 90.0 }
    };
    var res1 = values.Select(x => string.Format("{0}:{1}", x.Key, x.Value))
                    .Aggregate((current, next) => current + ", " + next);
    Console.WriteLine(res1);
    

    This has the advantage of using 7 the first string element as the seed (no prepended 6 ", "), but will consume more memory for 5 the strings created in the process.

  2. Use an 4 aggregate overload that accepts a seed, perhaps 3 a StringBuilder:

    var res2 = values.Aggregate(new StringBuilder(),
        (current, next) => current.AppendFormat(", {0}:{1}", next.Key, next.Value),
        sb => sb.Length > 2 ? sb.Remove(0, 2).ToString() : "");
    Console.WriteLine(res2);
    

    The second delegate converts our StringBuilder into 2 a string, using the conditional to trim the starting 1 ", ".

Score: 6

Aggregate has 3 overloads, so you could 5 use the one that has different type to accumulate 4 the items you are enumerating.

You would 3 need to pass in a seed value (your custom 2 class), and a method to add merge the seed 1 with one value. Example:

MyObj[] vals = new [] { new MyObj(1,100), new MyObj(2,200), ... };
MySum result = vals.Aggregate<MyObj, MySum>(new MySum(),
    (sum, val) =>
    {
       sum.Sum1 += val.V1;
       sum.Sum2 += val.V2;
       return sum;
    }
Score: 4

The Aggregate function accepts a delegate 2 parameter. You define the behavior you 1 want by changing the delegate.

var res = data.Aggregate((current, next) => current + ", " + next.Key + ": " + next.Value);

More Related questions