要的SelectMany扁平化嵌套结构 [英] SelectMany to flatten a nested structure

查看:392
本文介绍了要的SelectMany扁平化嵌套结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我解析XML结构和我的课如下所示:

I am parsing an XML structure and my classes look like the following:

class MyXml
{
    //...

    List<Node> Content { get; set; }

    //...
}

class Node
{
    // ...

    public List<Node> Nodes { get; set; }
    public string Type { get; set; }

    //...
}



与myXML代表XML文件我解析,它的元素都被称为<节点> 。每个节点有一个类型的属性,其可以具有不同的值。

MyXml represents the XML file I am parsing, whose elements are all called <node>. Each node has a type attribute, which can have different values.

类型的节点没有连接到它的深度。我可以在任何深度级别的任何节点类型。

The type of the node is not connected to its depth. I can have any node type at any depth level.

我能正确解析结构,使我得到一个与myXML对象,其内容为节点,在以往的节点列表在列表中可以有子节点等(我用的是递归)。

I can parse the structure correctly, so I get a MyXml object whose content is a list of Nodes, where ever node in the List can have subnodes and so on (I used recursion for that).

我需要做的是扁平化这一整体结构并提取一定的只有节点是什么键入

What I need to do is flatten this whole structure and extract only the nodes of a certain type.

我试着用:

var query = MyXml.Content.SelectMany(n => n.Nodes);



但它只取为1。结构的深度,我想抓住每一个节点的节点,无论深度,在同一个集合,然后筛选我需要什么。

but it's taking only the nodes with a structure depth of 1. I would like to grab every node, regardless of depth, in the same collection and then filter what I need.

推荐答案

这是一种自然的递归问题。使用递归的lambda,尝试这样的:

This is a naturally recursive problem. Using a recursive lambda, try something like:

Func<Node, IEnumerable<Node>> flattener = null;
flattener = n => new[] { n }
    .Concat(n.Nodes == null 
        ? Enumerable.Empty<Node>()
        : n.Nodes.SelectMany(flattener));

请注意,当你犯了一个递归函数功能这样,你必须声明函数功能单独第一,并将其​​设置为null。

Note that when you make a recursive Func like this, you must declare the Func separately first, and set it to null.

您也可以拼合使用迭代器块方法列表:

You could also flatten the list using an iterator-block method:

public static IEnumerable<Node> Flatten(Node node)
{
    yield return node;
    if (node.Nodes != null)
    {
        foreach(var child in node.Nodes)
            foreach(var descendant in Flatten(child))
                yield return descendant;
    }
}



无论哪种方式,一旦树被夷为平地,你可以做简单的LINQ查询在扁平列表来查找节点:

Either way, once the tree is flattened you can do simple Linq queries over the flattened list to find nodes:

flattener(node).Where(n => n.Type == myType);






响应改编自:的 http://stackoverflow.com/a/17086572/1480391

这篇关于要的SelectMany扁平化嵌套结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆