首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LINQ中嵌套列表到多级字典

LINQ中嵌套列表到多级字典
EN

Stack Overflow用户
提问于 2015-06-23 02:08:08
回答 2查看 935关注 0票数 1

我有以下课程

代码语言:javascript
复制
public class TreeNode
{
    public string Id { get; set; }
    public int Data { get; set; }
    public List<TreeNode> Children { get; private set; }


    public TreeNode(string node, int data)
    {
        Id = node;
        Data = data;
        Children = new List<TreeNode>();
    }

     public TreeNode(string node, params TreeNode[] children)
     {
        Id = node;
        Children = new List<TreeNode>(children);
     }

    public override string ToString()
    {
        return Id;
    }
} 

它是一棵n进制树,其中只有叶节点(没有子节点)才会填充数据属性。我希望使用LINQ将这个嵌套列表转换为多级字典。例如,如果树如下所示

代码语言:javascript
复制
TreeNode rootNode =
new TreeNode("node-0",
    new TreeNode("node-1",
        new TreeNode("node-2", 20)),
    new TreeNode("node-3", 19),
    new TreeNode("node-4",
        new TreeNode("node-5", 25),
        new TreeNode("node-6", 40)));

我希望上述结构被转换为字典(注:非平面字典),如下所示,使用LINQ。我需要词根字典作为LINQ的结果。我该怎么做。请帮帮我。

代码语言:javascript
复制
Dictionary<string, object> d4 = new Dictionary<string, object>();
d4.Add("node-5", 25);
d4.Add("node-6", 40);
Dictionary<string, object> d3 = new Dictionary<string, object>();
d3.Add("node-4", d4);
Dictionary<string, object> d2 = new Dictionary<string, object>();
d2.Add("node-2", 20);
Dictionary<string, object> d1 = new Dictionary<string, object>();
d1.Add("node-1", d2);
d1.Add("node-3", 19);
d1.Add("node-4", d4);
Dictionary<string, object> root = new Dictionary<string, object>();
root.Add("node-0", d1);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-23 02:58:17

更新:

由于问题不是关于扁平层次结构,而且用户正在为给定的输入寻找分层Dictionary,所以我对代码做了一些修改。

代码语言:javascript
复制
public static void Main()
{
    var rootNode =
        new TreeNode("node-0",
            new TreeNode("node-1",
                new TreeNode("node-2", 20)),
            new TreeNode("node-3", 19),
            new TreeNode("node-4",
                new TreeNode("node-5", 25),
                new TreeNode("node-6", 40)));


    var result = ReadHierarchy(new List<TreeNode> {rootNode});

    foreach (var r in result)
    {
        Console.WriteLine("{0} - {1}", r.Key, r.Value);
    }

    Console.ReadKey();
}

private static Dictionary<string, object> ReadHierarchy(IEnumerable<TreeNode> collection)
{
    return collection.ToDictionary(node => node.Id,
        node => node.Children.Count > 0 ? ReadHierarchy(node.Children) : node.Data as object);
}

工作fiddler示例

下面的解决方案扁平层次结构(如果需要的话使用)。

下面是简单的递归方法,它以List作为输入并返回扁平集合。

代码语言:javascript
复制
static List<TreeNode> ReadHierarchy(List<TreeNode> collection) 
{
    return collection.SelectMany(c => ReadHierarchy(c.Children)).Concat(collection).ToList();
} 

可以使用简单的Linq语句将返回的列表转换为Dictionary

代码语言:javascript
复制
TreeNode rootNode =
    new TreeNode("node-0",
                 new TreeNode("node-1",
                              new TreeNode("node-2", 20)),
                 new TreeNode("node-3", 19),
                 new TreeNode("node-4",
                              new TreeNode("node-5", 25),
                              new TreeNode("node-6", 40)));


var result = ReadHierarchy(new List<TreeNode> {rootNode}).ToDictionary(c=>c.Id, c=>c); 

工作Fiddler示例

票数 1
EN

Stack Overflow用户

发布于 2015-06-23 13:27:39

也许在treenode本身中实现getvalue逻辑会更好,但是如果不使用递归,下面的操作应该可以实现:

代码语言:javascript
复制
Func<TreeNode, object> getvalue = null;
getvalue = tn => tn.Children.Count == 0 ? (object)tn.Data : tn.Children.ToDictionary(n => n.Id, getvalue);
var result = getvalue(rootNode) as Dictionary<string, object>;

注意,这假设根始终包含子元素,否则getvalue将返回根节点的“数据”。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30992746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档