Linq 将复杂类型聚合成字符串
-
19-09-2019 - |
题
我见过 .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"
解决方案
您有两个选择:
项目到一个
string
然后聚合: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
元素作为种子(没有前缀“,”),但会为进程中创建的字符串消耗更多内存。使用接受种子的聚合重载,也许是
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,
使用条件来修剪开头的“,”。
其他提示
聚集体具有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;
}
在聚合函数接受一个代表参数。您可以通过更改委托定义你想要的行为。
var res = data.Aggregate((current, next) => current + ", " + next.Key + ": " + next.Value);
或者使用的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);
不隶属于 StackOverflow