gpt4 book ai didi

c# - 递归列表展平

转载 作者:IT王子 更新时间:2023-10-29 04:04:16 24 4
gpt4 key购买 nike

我可能会自己写这篇文章,但我试图完成它的具体方式让我失望了。我正在尝试编写一种类似于 .NET 3.5 中引入的其他扩展方法的通用扩展方法,它将采用嵌套的 IEnumerable 的 IEnumerable(等等)并将其展平为一个 IEnumerable。有人有什么想法吗?

具体来说,我在扩展方法本身的语法方面遇到了问题,因此我可以处理展平算法。

最佳答案

这是一个可能有用的扩展。它将遍历对象层次结构中的所有节点并挑选出符合条件的节点。它假定层次结构中的每个对象都具有一个集合属性,用于保存其子对象。

这是扩展:

/// Traverses an object hierarchy and return a flattened list of elements
/// based on a predicate.
///
/// TSource: The type of object in your collection.</typeparam>
/// source: The collection of your topmost TSource objects.</param>
/// selectorFunction: A predicate for choosing the objects you want.
/// getChildrenFunction: A function that fetches the child collection from an object.
/// returns: A flattened list of objects which meet the criteria in selectorFunction.
public static IEnumerable<TSource> Map<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> selectorFunction,
Func<TSource, IEnumerable<TSource>> getChildrenFunction)
{
// Add what we have to the stack
var flattenedList = source.Where(selectorFunction);

// Go through the input enumerable looking for children,
// and add those if we have them
foreach (TSource element in source)
{
flattenedList = flattenedList.Concat(
getChildrenFunction(element).Map(selectorFunction,
getChildrenFunction)
);
}
return flattenedList;
}

示例(单元测试):

首先我们需要一个对象和一个嵌套的对象层次结构。

一个简单的节点类

class Node
{
public int NodeId { get; set; }
public int LevelId { get; set; }
public IEnumerable<Node> Children { get; set; }

public override string ToString()
{
return String.Format("Node {0}, Level {1}", this.NodeId, this.LevelId);
}
}

以及获取节点的 3 级深层层次结构的方法

private IEnumerable<Node> GetNodes()
{
// Create a 3-level deep hierarchy of nodes
Node[] nodes = new Node[]
{
new Node
{
NodeId = 1,
LevelId = 1,
Children = new Node[]
{
new Node { NodeId = 2, LevelId = 2, Children = new Node[] {} },
new Node
{
NodeId = 3,
LevelId = 2,
Children = new Node[]
{
new Node { NodeId = 4, LevelId = 3, Children = new Node[] {} },
new Node { NodeId = 5, LevelId = 3, Children = new Node[] {} }
}
}
}
},
new Node { NodeId = 6, LevelId = 1, Children = new Node[] {} }
};
return nodes;
}

第一个测试:扁平化层次结构,没有过滤

[Test]
public void Flatten_Nested_Heirachy()
{
IEnumerable<Node> nodes = GetNodes();
var flattenedNodes = nodes.Map(
p => true,
(Node n) => { return n.Children; }
);
foreach (Node flatNode in flattenedNodes)
{
Console.WriteLine(flatNode.ToString());
}

// Make sure we only end up with 6 nodes
Assert.AreEqual(6, flattenedNodes.Count());
}

这将显示:

Node 1, Level 1
Node 6, Level 1
Node 2, Level 2
Node 3, Level 2
Node 4, Level 3
Node 5, Level 3

第二个测试:获取具有偶数 NodeId 的节点列表

[Test]
public void Only_Return_Nodes_With_Even_Numbered_Node_IDs()
{
IEnumerable<Node> nodes = GetNodes();
var flattenedNodes = nodes.Map(
p => (p.NodeId % 2) == 0,
(Node n) => { return n.Children; }
);
foreach (Node flatNode in flattenedNodes)
{
Console.WriteLine(flatNode.ToString());
}
// Make sure we only end up with 3 nodes
Assert.AreEqual(3, flattenedNodes.Count());
}

这将显示:

Node 6, Level 1
Node 2, Level 2
Node 4, Level 3

关于c# - 递归列表展平,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/141467/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com