private static IEnumerable <T> DescendantsCore <T, K>(IEnumerable <T> source, Func <T, K> keySelector, Func <T, K> parentKeySelector, Equality <K> equality, K startKey, bool descendantsOnly = false, int?levelsCount = null) where T : class where K : class { PwrList <T> list = new PwrList <T>(); PwrFrameListView <T> view = new PwrFrameListView <T>(list); int priorCount = list.Count; if (descendantsOnly) { list.AddRange(source.Where(t => equality(parentKeySelector(t), startKey))); } else if (startKey != null) { list.AddRange(source.Where(t => equality(keySelector(t), startKey))); } int takeCount = list.Count - priorCount; for (int passCount = 1; (!levelsCount.HasValue || levelsCount.Value > passCount) && takeCount > 0; passCount++) { view.FrameOffset = priorCount; view.FrameSize = takeCount; priorCount = list.Count; list.AddRange(source.Where(t1 => parentKeySelector(t1) != null && view.Any(t2 => equality(keySelector(t2), parentKeySelector(t1))))); takeCount = list.Count - priorCount; } return(list.AsEnumerable()); }
public static IEnumerable <String> ReadLines(this TextReader reader, Func <IList <Char>, int> terminatorMatcher, Func <IList <Char>, string> terminatorConverter, int maxCount) { if (reader == null) { throw new ArgumentNullException("reader"); } if (terminatorMatcher == null) { throw new ArgumentNullException("matchTerm"); } if (maxCount < 0) { throw new ArgumentOutOfRangeException("maxCount"); } if (maxCount == 0) { yield break; } int matched = 0; var list = new PwrList <Char>(); var view = new PwrFrameListView <Char>(list); var sb = new StringBuilder(); while (maxCount > 0) { int read = 0; int accepted = 0; while (true) { if (matched == list.Count) { if ((read = reader.Read()) < 0) { break; } else { list.PushLast((char)read); } } view.FrameSize = matched + 1; accepted = terminatorMatcher(view); if (accepted > 0) { break; } else if (accepted == 0) { matched++; } else { matched = 0; sb.Append(list.PopFirst()); } } if (accepted > matched + 1) { throw new InvalidOperationException("Accepted value is greater matched length."); } if (accepted > 0) { if (terminatorConverter == null) { sb.Append(list.GetRange(0, accepted).ToArray()); } else { view.FrameSize = accepted; string term = terminatorConverter(view); if (!string.IsNullOrEmpty(term)) { sb.Append(term); } } yield return(sb.ToString()); sb.Clear(); list.RemoveRange(0, accepted); matched = 0; maxCount--; } if (read < 0) { break; } } if (maxCount > 0) { if (list.Count > 0) { sb.AppendChars(list); } if (sb.Length > 0) { yield return(sb.ToString()); sb.Clear(); list.Clear(); } } }