How can I get similar functionality to doc.Descendants() using linq against a collection of objects that contains sub collections of the same objects X levels deep?
The last nested collection contains the data in need to get at, all the other parent collections are merely groupings. I could transform the collection to an XDocument and call the descendants function but I would prefer to mimic that functionality against this object collection.
public class ProductLine
{
public string Id {get;set;}
public string ParentId {get;set;}
public string Name {get;set;}
public string Type {get;set;}
public string Level {get;set;}
public IEnumerable<ProductLine> Childr开发者_如何学JAVAen {get;set;}
}
I can have a list of ProductLine that contains child lists of ProductLine. The nested levels can vary depending on how the data was set up so I never know how many levels there are. The bottom most list will have a Type="Model" while every list prior will have a Type="Series" resulting in something like:
Series1
Series2
Series3
Model1
Model1
Series2
Model3
Model4
With this Node class, the solution is quite easy.
Change the ProductLineClass a litte bit:
public class ProductLine
{
public int Id { get; set; }
public int? ParentId { get; set; }
public string Name { get; set; }
public string Type { get; set; }
// The level property is no longer needed because it is a property of the Node class
public IEnumerable<ProductLine> Children { get; set; }
}
Create a tree:
var productlinesInAFlatList = GetListOfproductLines();
// Create alle the trees that can me made with the flad list based on Id and ParentId's
var rootNodes = Node<ProductLine>.CreateTree(productlinesInAFlatList, p => p.Id, p => p.ParentId);
// Assume there is only one tree in this flat ist
var rootNode = rootNodes.Single();
Get all info you need:
// Get the nodes that has no childnodes
var nodesWithoutChildNodes = rootNode.Descendants.Where(n => !n.Descendants.Any());
// If you just want the values of this childnodes
var values = nodesWithoutChildNodes.Values();
// When you need the levels of the values
var levels = nodesWithoutChildNodes.Select(n => n.Level);
You can use Linq's SelectMany
function.
IEnumerable<ProductLine> products = <something>;
IEnumerable<ProductLine> modelProducts = products
.SelectMany((x) => x.Children)
However, this will only flatten to one depth. You need to look a Recursive SelectMany for the full effect. See the following links for more advice.
- recursive list flattening
- is it possible to implement a recursive selectmany
精彩评论