今天我要实现一种方法来遍历任意深度图并将其展平为单个可枚举.相反,我先做了一点搜索,发现了这个:
public static IEnumerable<T> Traverse<T>(this IEnumerable<T> enumerable, Func<T, IEnumerable<T>> recursivePropertySelector)
{
foreach (T item in enumerable)
{
yield return item;
IEnumerable<T> seqRecurse = recursivePropertySelector(item);
if (seqRecurse == null) continue;
foreach (T itemRecurse in Traverse(seqRecurse, recursivePropertySelector))
{
yield return itemRecurse;
}
}
}
Run Code Online (Sandbox Code Playgroud)
从理论上讲,这看起来很不错,但实际上我发现它比使用等效的手写代码(如果出现的情况)执行图表并做任何需要做的事情要差得多.我怀疑这是因为在这个方法中,对于它返回的每个项目,堆栈必须放松到某个任意深度的水平.
我还怀疑如果递归被消除,这种方法会更有效地运行.我也不太擅长消除递归.
有谁知道如何重写此方法以消除递归?
谢谢你的帮助.
编辑:非常感谢所有详细的回复.我已尝试对原始解决方案与Eric的解决方案进行基准测试,而不是使用枚举器方法,而是递归遍历一个lambda,奇怪的是,lambda递归明显快于其他两种方法.
class Node
{
public List<Node> ChildNodes { get; set; }
public Node()
{
ChildNodes = new List<Node>();
}
}
class Foo
{
public static void Main(String[] args)
{
var nodes = new List<Node>(); …Run Code Online (Sandbox Code Playgroud) 我需要迭代 JsonDocument 并根据我遇到的情况执行某种检查JsonValueKind。
我尝试以这种方式进行验证检查:
public bool Dec(JsonElement Element)
{
var ElementEnumeratable = Element.EnumerateObject();
foreach (var Elm in ElementEnumeratable )
{
string name = Elm.Name;
switch (Elm.Value.ValueKind)
{
case JsonValueKind.Array:
var jArray = Elm.Value;
return Dec(jArray);
case JsonValueKind.String:
string jString = Elm.Value.GetString();
break;
case JsonValueKind.Number:
int jNumber = Elm.Value.GetInt32();
break;
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是当Elm有ValueKind数组时 - 我无法将它传递给Dec看起来JsonElement有 valuekind 作为数组的数组,无法转换为EnumerateObject?
在这里做什么?