Source code for this blog post.
1: /// <summary>
2: /// Recursively projects each nested element to an <see cref="IEnumerable{TSource}"/>
3: /// and flattens the resulting sequences into one sequence.
4: /// </summary>
5: /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
6: /// <param name="source">A sequence of values to project.</param>
7: /// <param name="recursiveSelector">A transform to apply to each element.</param>
8: /// <returns>
9: /// An <see cref="IEnumerable{TSource}"/> whose elements are the
10: /// result of recursively invoking the recursive transform function
11: /// on each element and nested element of the input sequence.
12: /// </returns>
13: public static IEnumerable<TSource> SelectRecursive<TSource>(
14: this IEnumerable<TSource> source, Func<TSource, IEnumerable<TSource>> recursiveSelector)
15: {
16: Util.RequireNotNull(source, "start");
17: Util.RequireNotNull(recursiveSelector, "children");
18:
19: Stack<TSource> stack = new Stack<TSource>();
20:
21: source.Reverse().ForEach(stack.Push);
22:
23: while (stack.Count > 0)
24: {
25: TSource current = stack.Pop();
26:
27: recursiveSelector(current).Reverse().ForEach(stack.Push);
28:
29: yield return current;
30:
31: } // while
32:
33: } //*** SelectRecursive
34:
35: /// <summary>
36: /// Performs the specified <paramref name="action"/> to
37: /// on each element of the specified <paramref name="source"/>.
38: /// </summary>
39: /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
40: /// <param name="source">The sequence to which is applied the specified <paramref name="action"/>.</param>
41: /// <param name="action">The action applied to each element in <paramref name="source"/>.</param>
42: public static void ForEach<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
43: {
44: Util.RequireNotNull(source, "source");
45: Util.RequireNotNull(action, "action");
46:
47: foreach (TSource item in source)
48: {
49: action(item);
50: }
51: }