अपडेट करें:
नेस्टिंग (गहराई) के स्तर में रुचि रखने वाले लोगों के लिए। स्पष्ट एन्यूमरेटर स्टैक कार्यान्वयन के बारे में अच्छी चीजों में से एक यह है कि किसी भी समय (और विशेष रूप से जब तत्व की उपज) 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);
मूल:
आश्चर्यजनक रूप से कोई भी (यहां तक कि एरिक) ने एक पुनरावर्ती पूर्व-आदेश डीएफटी के "प्राकृतिक" पुनरावृत्त बंदरगाह को दिखाया, इसलिए यहां यह है:
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();
}
}