How to sort depended objects by dependency

后端 未结 10 549
青春惊慌失措
青春惊慌失措 2020-11-28 19:31

I have a collection:

List> dependencyHierarchy;

The first item in pair is some object (item) and the

10条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-28 20:06

    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
        }
    
    }
    

提交回复
热议问题