최신 정보:
중첩 수준 (깊이)에 관심이있는 사람들을위한 것입니다. 명시 적 열거 자 스택 구현에 대한 좋은 점 중 하나는 언제든지 (특히 요소를 생성 할 때) stack.Count
현재 처리 깊이를 나타냅니다. 따라서이를 고려하고 C # 7.0 값 튜플을 활용하여 다음과 같이 메서드 선언을 간단히 변경할 수 있습니다.
public static IEnumerable<(T Item, int Level)> ExpandWithLevel<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> elementSelector)
및 yield
성명 :
yield return (item, stack.Count);
그런 다음 Select
위의 간단한 방법을 적용하여 원래 방법을 구현할 수 있습니다 .
public static IEnumerable<T> Expand<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> elementSelector) =>
source.ExpandWithLevel(elementSelector).Select(e => e.Item);
실물:
놀랍게도 아무도 (심지어 Eric) 재귀 적 선주문 DFT의 "자연스러운"반복 포트를 보여주지 않았으므로 다음과 같습니다.
public static IEnumerable<T> Expand<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> elementSelector)
{
var stack = new Stack<IEnumerator<T>>();
var e = source.GetEnumerator();
try
{
while (true)
{
while (e.MoveNext())
{
var item = e.Current;
yield return item;
var elements = elementSelector(item);
if (elements == null) continue;
stack.Push(e);
e = elements.GetEnumerator();
}
if (stack.Count == 0) break;
e.Dispose();
e = stack.Pop();
}
}
finally
{
e.Dispose();
while (stack.Count != 0) stack.Pop().Dispose();
}
}