30

我已经看到 .net Aggregate 函数的简单示例是这样工作的:

string[] words = { "one", "two", "three" };
var res = words.Aggregate((current, next) => current + ", " + next);
Console.WriteLine(res);

如果您希望聚合更复杂的类型,如何使用“聚合”函数?例如:一个具有 2 个属性的类,例如 'key' 和 'value',并且您想要这样的输出:

"MyAge: 33, MyHeight: 1.75, MyWeight:90"
4

4 回答 4

57

你有两个选择:

  1. 投影到 astring然后聚合:

    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);
    

    这样做的好处是使用第一个string元素作为种子(没有前置“,”),但会为进程中创建的字符串消耗更多内存。

  2. 使用接受种子的聚合重载,可能是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);
    

    第二个委托将我们StringBuilder转换为string,使用条件来修剪开始的“,”。

于 2009-10-02T11:42:51.097 回答
6

Aggregate 有 3 个重载,因此您可以使用具有不同类型的重载来累积要枚举的项目。

您需要传入一个种子值(您的自定义类),以及一个方法来添加将种子与一个值合并。例子:

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;
    }
于 2009-10-02T02:40:54.150 回答
4

Aggregate 函数接受委托参数。您可以通过更改委托来定义您想要的行为。

var res = data.Aggregate((current, next) => current + ", " + next.Key + ": " + next.Value);
于 2009-10-02T02:33:04.443 回答
-1

或使用 string.Join() :

var values = new[] {
    new { Key = "MyAge", Value = 33.0 },
    new { Key = "MyHeight", Value = 1.75 },
    new { Key = "MyWeight", Value = 90.0 }
};
var res = string.Join(", ", values.Select(item => $"{item.Key}: {item.Value}"));
Console.WriteLine(res);
于 2018-03-18T12:54:00.837 回答