static IEnumerable <T> FlattenFromWithin <T>(this IEnumerable <T> rootPath, Func <T, IList <T> > getChildren, Func <IList <T>, T, int> indedOf, Func <IImmutableStack <T>, Func <T, IList <T> >, Func <IList <T>, T, int>, IImmutableStack <T> > getNextElement) where T : class { indedOf = indedOf ?? ((list, item) => list.IndexOf(item)); var originalStack = rootPath.ToImmutableStack(); Func <IImmutableStack <T>, IImmutableStack <T> > next = x => { var nextElement = getNextElement(x, getChildren, indedOf); return(nextElement.Peek() == originalStack.Peek() ? null : nextElement); }; return(LinqExtensions.Unfold(originalStack, next, x => x == null).Select(x => x.Peek())); }
static IImmutableStack <T> GetPrevElementInHierarchyCore <T>(IImmutableStack <T> rootStack, Func <T, IList <T> > getChildren, Func <IList <T>, T, int> indedOf) where T : class { var currentElement = rootStack.Peek(); Func <T, IEnumerable <T> > getChildrenPath = element => LinqExtensions.Unfold(element, x => getChildren(x).LastOrDefault(), x => x == null); var parents = rootStack.Pop(); var parent = parents.FirstOrDefault(); if (parent == null) { return(ImmutableStack.Empty <T>().PushMultiple(getChildrenPath(currentElement))); } var neighbors = getChildren(parent); var index = indedOf(neighbors, currentElement); if (index > 0) { return(parents.PushMultiple(getChildrenPath(neighbors[index - 1]))); } return(parents); }
static IEnumerable <Type> GetAttributeTypes(Attribute attr) { return(LinqExtensions.Unfold(attr.GetType(), x => x.BaseType, x => x == typeof(Attribute))); }