我有一个字典,其中键是一个字符串,值是与该键对应的字符串列表。我想显示字典中的所有键,以及与该键关联的值在该键下方的选项卡中。像这样:
Key 1
Value 1
Value 2
Value 3
Key 2
Value 1
Value 2
在 C# 2.0 中,我会这样做(values
是 Dictionary
):
StringBuilder sb = new StringBuilder();
foreach(KeyValuePair<string, List<string>> pair in values)
{
sb.AppendLine(pair.Key);
foreach(string item in pair.Value)
{
sb.AppendLine('\t' + item);
}
}
我将如何使用 LINQ 执行等效操作?看起来应该是可能的,但我不知道该怎么做。
如果我使用 values.SelectMany(p => p.Values)
,那么只有值会出现在最终结果中,键不会出现。
我想到的任何其他解决方案都有类似的限制。
最佳答案
C# 中的解决方案
这是一个使用 aggregate extension method 的解决方案:
string result = values.Aggregate("",
(keyString, pair) =>
keyString + "\n" + pair.Key + ":"
+ pair.Value.Aggregate("",
(str, val) => str + "\n\t" + val)
);
C# 中的聚合子句没有 LINQ 语法(但显然在 Visual Basic 中有一些预定义函数)。
这个解决方案可能看起来有些复杂,但聚合方法非常有用。
聚合的工作原理
它是这样工作的:如果你有一个 List<int>
您可以将所有值组合成一个单个聚合值。
这与 Select
形成对比方法,它不会修改列表的长度。或者 Where
方法,它确实缩小了列表,但它仍然是一个列表(而不是单个值)。
例如,如果您有一个列表 {1, 2, 3, 4}
您可以像这样将它们组合成一个值:
int[] xs = {1, 2, 3, 4};
int sum = xs.Aggregate(0, (sumSoFar, x) => sumSoFar + x);
所以你给 Aggregate
两个值方法;一个种子值和一个“组合器”函数:
- 您开始使用单个种子值(在本例中为
0
)进行聚合。 - 您的组合器函数会针对列表中的每个值被调用。
第一个参数是到目前为止的计算结果(第一次为零,稍后会有其他值),并将其与值x
组合.
简而言之,Aggregate
方法适用于 List<int>
.它在 KeyValuePair<string, List<string>>
上工作相同, 但只是类型不同。
关于c# - 如何使用 LINQ 将字典的键和值组合到一个列表中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/753321/