Last active
July 26, 2018 03:38
-
-
Save alonstar/74a40641913effd6b7eed55614b77c41 to your computer and use it in GitHub Desktop.
Make trees
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Defines the <see cref="Extensions" /> | |
/// </summary> | |
public static class TreeExtensions | |
{ | |
/// <summary> | |
/// The FindChildren | |
/// </summary> | |
/// <typeparam name="T">T</typeparam> | |
/// <param name="source">The source<see cref="IEnumerable{Node{T}}"/></param> | |
/// <param name="predicate">The predicate<see cref="Func{Node{T}, bool}"/></param> | |
/// <returns>The <see cref="IEnumerable{Node{T}}"/></returns> | |
public static IEnumerable<Node<T>> FindChildren<T>(this IEnumerable<Node<T>> source, Func<Node<T>, bool> predicate) | |
{ | |
return source.FindNode(predicate).Children.Flatten(p => p.Children); | |
} | |
/// <summary> | |
/// The FindNode | |
/// </summary> | |
/// <typeparam name="T">T</typeparam> | |
/// <param name="source">The source<see cref="IEnumerable{Node{T}}"/></param> | |
/// <param name="predicate">The predicate<see cref="Func{Node{T}, bool}"/></param> | |
/// <returns>The <see cref="Node{T}"/></returns> | |
public static Node<T> FindNode<T>(this IEnumerable<Node<T>> source, Func<Node<T>, bool> predicate) | |
{ | |
return source.Flatten(p => p.Children).FirstOrDefault(predicate); | |
} | |
/// <summary> | |
/// The FindParents | |
/// </summary> | |
/// <typeparam name="T">T</typeparam> | |
/// <param name="source">The source<see cref="Node{T}"/></param> | |
/// <returns>The <see cref="IEnumerable{Node{T}}"/></returns> | |
public static IEnumerable<Node<T>> FindParents<T>(this Node<T> source) | |
{ | |
var root = source; | |
var list = new List<Node<T>>(); | |
while (root.Parent != null) | |
{ | |
list.Add(root.Parent); | |
root = root.Parent; | |
} | |
return list; | |
} | |
/// <summary> | |
/// The Flatten | |
/// </summary> | |
/// <typeparam name="T">T</typeparam> | |
/// <param name="source">The source<see cref="IEnumerable{T}"/></param> | |
/// <param name="f">The f<see cref="Func{T, IEnumerable{T}}"/></param> | |
/// <returns>The <see cref="IEnumerable{T}"/></returns> | |
public static IEnumerable<T> Flatten<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> f) | |
{ | |
return source.SelectMany(c => f(c).Flatten(f)).Concat(source); | |
} | |
/// <summary> | |
/// The Hierarchize | |
/// </summary> | |
/// <typeparam name="T">T</typeparam> | |
/// <typeparam name="TKey">TKey</typeparam> | |
/// <typeparam name="TOrderKey">TOrderKey</typeparam> | |
/// <param name="elements">The elements<see cref="IEnumerable{T}"/></param> | |
/// <param name="rootId">The rootId<see cref="TKey"/></param> | |
/// <param name="keySelector">The keySelector<see cref="Func{T, TKey}"/></param> | |
/// <param name="parentKeySelector">The parentKeySelector<see cref="Func{T, TKey}"/></param> | |
/// <param name="orderKeySelector">The orderKeySelector<see cref="Func{T, TOrderKey}"/></param> | |
/// <returns>The <see cref="IEnumerable{Node{T}}"/></returns> | |
public static IEnumerable<Node<T>> Hierarchize<T, TKey, TOrderKey>( | |
this IEnumerable<T> elements, | |
TKey rootId, | |
Func<T, TKey> keySelector, | |
Func<T, TKey> parentKeySelector, | |
Func<T, TOrderKey> orderKeySelector) | |
{ | |
var families = elements.ToLookup(parentKeySelector); | |
var childrenFetcher = default(Func<TKey, Node<T>, IList<Node<T>>>); | |
childrenFetcher = (parentId, parent) => | |
{ | |
var children = families[parentId] | |
.OrderBy(orderKeySelector) | |
.Select(x => new Node<T>(x)) | |
.ToList(); | |
children.ForEach(c => | |
{ | |
c.Children = childrenFetcher(keySelector(c.Value), c); | |
c.Parent = parent; | |
}); | |
return children; | |
}; | |
return childrenFetcher(rootId, null); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment