I have a collection:
List> dependencyHierarchy;
The first item in pair is some object (item) and the
This is refactored code from post https://stackoverflow.com/a/9991916/4805491.
// Version 1
public static class TopologicalSorter where T : class {
public struct Item {
public readonly T Object;
public readonly T Dependency;
public Item(T @object, T dependency) {
Object = @object;
Dependency = dependency;
}
}
public static T[] Sort(T[] objects, Func isDependency) {
return Sort( objects.ToList(), isDependency ).ToArray();
}
public static T[] Sort(T[] objects, Item[] dependencies) {
return Sort( objects.ToList(), dependencies.ToList() ).ToArray();
}
private static List Sort(List objects, Func isDependency) {
return Sort( objects, GetDependencies( objects, isDependency ) );
}
private static List Sort(List objects, List- dependencies) {
var result = new List
( objects.Count );
while (objects.Any()) {
var obj = GetIndependentObject( objects, dependencies );
RemoveObject( obj, objects, dependencies );
result.Add( obj );
}
return result;
}
private static List- GetDependencies(List
objects, Func isDependency) {
var dependencies = new List- ();
for (var i = 0; i < objects.Count; i++) {
var obj1 = objects[i];
for (var j = i + 1; j < objects.Count; j++) {
var obj2 = objects[j];
if (isDependency( obj1, obj2 )) dependencies.Add( new Item( obj1, obj2 ) ); // obj2 is dependency of obj1
if (isDependency( obj2, obj1 )) dependencies.Add( new Item( obj2, obj1 ) ); // obj1 is dependency of obj2
}
}
return dependencies;
}
private static T GetIndependentObject(List
objects, List- dependencies) {
foreach (var item in objects) {
if (!GetDependencies( item, dependencies ).Any()) return item;
}
throw new Exception( "Circular reference found" );
}
private static IEnumerable
- GetDependencies(T obj, List
- dependencies) {
return dependencies.Where( i => i.Object == obj );
}
private static void RemoveObject(T obj, List
objects, List- dependencies) {
objects.Remove( obj );
dependencies.RemoveAll( i => i.Object == obj || i.Dependency == obj );
}
}
// Version 2
public class TopologicalSorter {
public static T[] Sort
(T[] source, Func isDependency) {
var list = new LinkedList( source );
var result = new List();
while (list.Any()) {
var obj = GetIndependentObject( list, isDependency );
list.Remove( obj );
result.Add( obj );
}
return result.ToArray();
}
private static T GetIndependentObject(IEnumerable list, Func isDependency) {
return list.First( i => !GetDependencies( i, list, isDependency ).Any() );
}
private static IEnumerable GetDependencies(T obj, IEnumerable list, Func isDependency) {
return list.Where( i => isDependency( obj, i ) ); // i is dependency of obj
}
}