C# LINQ - 将嵌套字典转换为列表

12

如何将嵌套字典展平为一些对象的列表(在下面的示例中为SomeObject),这些对象应该包含那些字典的键?

例如:假如我们有以下类型的字典

var nestedDictionary = new Dictionary<int, Dictionary<int, string>>();

那么,让我们来创建这个类

public class SomeObject
{
   public int var1;
   public int var2;
   public string someStringVar;
}

如何将 nestedDictionary 转换为一个列表 List<SomeObject>,其中 var1 是外层字典的键,var2 是内部字典的键,someStringVar 是内部字典的字符串值?

本质上,我该如何转移这个:

nestedDict[0][0] = "foo";
nestedDict[0][1] = "bar";
nestedDict[0][2] = "foo1";
nestedDict[1][0] = "bar1";
nestedDict[1][1] = "foo2";
nestedDict[1][2] = "bar2";

转化为以下内容(用伪C#表示只是为了可视化)

objList[0] = SomeObject { var1 = 0, var2 = 0, someStringVar = "foo" }
objList[1] = SomeObject { var1 = 0, var2 = 1, someStringVar = "bar" }
objList[2] = SomeObject { var1 = 0, var2 = 2, someStringVar = "foo1" }
objList[3] = SomeObject { var1 = 1, var2 = 0, someStringVar = "bar1" }
objList[4] = SomeObject { var1 = 1, var2 = 1, someStringVar = "foo2" }
objList[5] = SomeObject { var1 = 1, var2 = 2, someStringVar = "bar2" }

使用 LINQ?

4个回答

11

你可以使用 SelectMany(),并编写类似以下的代码:

var objList = nestedDictionary.SelectMany(
    pair => pair.Value.Select(
        innerPair => new SomeObject() {
            var1 = pair.Key,
            var2 = innerPair.Key,
            someStringVar = innerPair.Value
        })).ToList();

+1 SelectMany 是我倾向于使用查询语法(如果可能的话),不知道为什么。如果格式化得很好,方法语法在 C# 中也同样易读(不像 VB)。 - Tim Schmelter
@Tim,并不是说这有什么问题 :) 实际上我选择方法语法是因为最后的 ToList() 调用(出于某种原因,我不喜欢将查询语法与最终方法调用混合使用)。 - Frédéric Hamidi

9
这应该可以正常工作:
var flattened =
from kvpOuter in nestedDictionary
from kvpInner in kvpOuter.Value
select new SomeObject()
{
    var1 = kvpOuter.Key,
    var2 = kvpInner.Key,
    someStringVar = kvpInner.Value
};
var list = flattened.ToList(); // if you need a list...

似乎我在使用LINQ时往往会过于复杂化问题...我没能看到这么简单的解决方案。谢谢 :) - Mirek
谢谢!!!哇,我准备撞墙了,但现在一切都好了,我可以永远编码下去! - Robert Noack
如果您只想将嵌套字典作为列表返回,而不使用对象初始化程序,您会如何使用LINQ来完成这个任务? - JWiley
@JWiley:你想把每个嵌套的字典转换成列表(最终获得一个列表),还是想获得一个包含内部字典中所有键值的最终列表?你不能简单地从上面的代码中删除对象初始化器,你需要为每个内部字典元素返回一些东西(例如kvpInner)... - digEmAll
@JWiley:实际上,使用您的代码,您将获得键值对列表,而不是列表列表... - digEmAll
显示剩余3条评论

1
这将为您提供一个可枚举的 IEnumerable<SomeObject>
var results = from d in nestedDictionary
              from innerD in d.Value
              select new SomeObject { var1 = d.Key, var2 = innerD .Key, someStringVar = innerD .Value };

调用 results.ToListresults.ToArray 分别获取 List<SomeObject>SomeObject[]


0
var xxx = nestedDictionary.SelectMany(
                    kvp =>
                    kvp.Value.Select(
                        xx => new SomeObject() {var1 = kvp.Key, var2 = xx.Key, someStringVar = xx.Value}));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接