public List <string> CreateIncludeList(List <string> existing, List <IncludeEntry> requested) { var primaries = requested .Where(ie => ie.Dependencies == null) .Select(ie => ie.Include) .Concat(existing); // creates a list of lists where in each list each item depends on the ones before it List <List <string> > depLists = requested .Where(ie => !primaries.Contains(ie.Include)) .Select(ie => primaries .Concat(ie.Dependencies .Where(d => !primaries.Contains(d))) .Concat(ie.Include).ToList()) .ToList(); // distinct items in lists List <string> items = depLists.SelectMany(list => list).Distinct().ToList(); // build graph of ordering information ArrayGraph <string, bool> orderingGraph = new ArrayGraph <string, bool>(items) { Unidirectional = true }; for (int i = 0; i < depLists.Count; i++) { for (int j = 1; j < depLists[i].Count; j++) { for (int k = j - 1; k >= 0; k--) { orderingGraph[depLists[i][k], depLists[i][j]] = true; } } } // use it to order includes List <string> result = items .PartialOrderBy(s => s, orderingGraph) .ToList(); return(result); }
/// <summary> /// Build a sorted list of includes from existing includes in the document and requested/registered includes /// </summary> /// <param name="existing">Existing includes in the document</param> /// <param name="requested">Registered includes to add</param> /// <returns>List of include files or script, css or html snippets in order to insert in document</returns> public List <string> CreateIncludeList(List <IncludeEntry> existing, List <IncludeEntry> requested) { var primaries = requested .Where(ie => ie.Dependencies == null) .Select(ie => ie.Include) .Concat(existing.Select(ie => ie.Include)) .ToList(); var inclDict = existing .Concat(requested) .Where(ie => !string.IsNullOrEmpty(ie.Id)) .ToDictionary(ie => ie.Id, ie => ie.Include); // creates a list of lists where in each list each item depends on the ones before it List <List <string> > depLists = requested .Where(ie => !primaries.Contains(ie.Include)) .Select(ie => ie.Dependencies .Select(d => inclDict.ContainsKey(d) ? inclDict[d] : d) .Concat(ie.Include).ToList()) .ToList(); // if there are no dependencies, just return the list of primaries if (depLists.Count == 0) { return(primaries.ToList()); } // distinct items in lists List <string> items = depLists.SelectMany(list => list).Concat(primaries).Distinct().ToList(); // build graph of ordering information ArrayGraph <string, bool> orderingGraph = new ArrayGraph <string, bool>(items) { Unidirectional = true }; var iPrimaries = primaries.Select(p => orderingGraph.NodeIndex(p)).ToArray(); // ensure primaries retain same order for (int i = 1; i < iPrimaries.Length; i++) { for (int j = 0; j < i; j++) { orderingGraph[iPrimaries[j], iPrimaries[i]] = true; } } var iDepLists = depLists.Select(dl => dl.Select(dli => orderingGraph.NodeIndex(dli)).ToArray()).ToArray(); // add dependency lists for (int i = 0; i < iDepLists.Length; i++) { for (int j = 1; j < iDepLists[i].Length; j++) { for (int k = j - 1; k >= 0; k--) { orderingGraph[iDepLists[i][k], iDepLists[i][j]] = true; } } } // use it to order includes List <string> result = items .PartialOrderBy(s => s, orderingGraph) .ToList(); return(result); }
/// <summary> /// Build a sorted list of includes from existing includes in the document and requested/registered includes /// </summary> /// <param name="existing">Existing includes in the document</param> /// <param name="requested">Registered includes to add</param> /// <returns>List of include files or script, css or html snippets in order to insert in document</returns> public List<string> CreateIncludeList(List<IncludeEntry> existing, List<IncludeEntry> requested) { var primaries = requested .Where(ie => ie.Dependencies == null) .Select(ie => ie.Include) .Concat(existing.Select(ie => ie.Include)) .ToList(); var inclDict = existing .Concat(requested) .Where(ie => !string.IsNullOrEmpty(ie.Id)) .ToDictionary(ie => ie.Id, ie => ie.Include); // creates a list of lists where in each list each item depends on the ones before it List<List<string>> depLists = requested .Where(ie => !primaries.Contains(ie.Include)) .Select(ie => ie.Dependencies .Select(d => inclDict.ContainsKey(d) ? inclDict[d] : d) .Concat(ie.Include).ToList()) .ToList(); // if there are no dependencies, just return the list of primaries if (depLists.Count == 0) return primaries.ToList(); // distinct items in lists List<string> items = depLists.SelectMany(list => list).Concat(primaries).Distinct().ToList(); // build graph of ordering information ArrayGraph<string, bool> orderingGraph = new ArrayGraph<string, bool>(items) { Unidirectional = true }; var iPrimaries = primaries.Select(p => orderingGraph.NodeIndex(p)).ToArray(); // ensure primaries retain same order for (int i = 1; i < iPrimaries.Length; i++) for (int j = 0; j < i; j++) orderingGraph[iPrimaries[j], iPrimaries[i]] = true; var iDepLists = depLists.Select(dl => dl.Select(dli => orderingGraph.NodeIndex(dli)).ToArray()).ToArray(); // add dependency lists for (int i = 0; i < iDepLists.Length; i++) for (int j = 1; j < iDepLists[i].Length; j++) for (int k = j - 1; k >= 0; k--) orderingGraph[iDepLists[i][k], iDepLists[i][j]] = true; // use it to order includes List<string> result = items .PartialOrderBy(s => s, orderingGraph) .ToList(); return result; }