public static IEnumerable <Tuple <T, IEnumerable <T> > > RecursivelyDescendHelper <T>( this T seed, IEnumerable <T> initAccumulator, AccumulatorInclusion accumulatorTerminalInclusion, Func <T, bool> terminateOnDescendent, Func <T, IEnumerable <T> > getDescendents) where T : class { // ideally a linked arraylist would be used here. if (terminateOnDescendent(seed)) { if (accumulatorTerminalInclusion == AccumulatorInclusion.Include) { return(new Tuple <T, IEnumerable <T> >(seed, initAccumulator.Concat(seed)).Wrap()); } else { return(new Tuple <T, IEnumerable <T> >(seed, initAccumulator).Wrap()); } } else //seed is intermediate { initAccumulator = initAccumulator.Concat(seed); var descendents = getDescendents(seed); var results = descendents.Select( (d) => RecursivelyDescendHelper( d, initAccumulator, accumulatorTerminalInclusion, terminateOnDescendent, getDescendents ) ).SelectMany(r => r); return(results); } }
public static IEnumerable <Tuple <T, IEnumerable <T> > > RecursivelyDescend <T>( this T seed, IEnumerable <T> initAccumulator, AccumulatorInclusion accumulatorSeedInclusion, AccumulatorInclusion accumulatorTerminalInclusion, Func <T, bool> terminateOnDescendent, Func <T, IEnumerable <T> > getDescendents) where T : class { if (accumulatorSeedInclusion == AccumulatorInclusion.Include) { initAccumulator = initAccumulator.Concat(seed); } return(getDescendents(seed).Select( descendent => RecursivelyDescendHelper( descendent, initAccumulator, accumulatorTerminalInclusion, terminateOnDescendent, getDescendents ) ).SelectMany(many => many)); }