文件依赖性按正确顺序排列

时间:2014-11-28 21:58:10

标签: javascript algorithm graph

我对依赖项有疑问。有以下对象:

var files = {
    "f": {"dep": ["b", "c"]},
    "g": {"dep": ["e", "f"]},
    "a": {"dep": ["c", "b"]},
    "b": {"dep": ["d", "c"]},
    "c": {"dep": []},
    "d": {"dep": ["c"]},
    "e": {"dep": ["a"]}
};

需要一种方法来创建一个所有文件(字母)的序列,我不会搞砸文件的依赖顺序(f不会出现在b和c之前)。所以我的想法就是遍历它,就像我会进行图形爬行一样。

//TODO -o :if we have e.g "a" depend on "b" and "b" depend on "a" this will lead to
//TODO -o :infinite recursion - so we should handle this scenario.

//Todo -o :It could be optimized by checking if the file is already visited.
//stores all files in dependant order
var filesInDependantOrder = [];

//loop through all files
for (var file in files)
{
    //call the drillDownDependencies to drill down to all files
    drillDownDependencies( files[file] );

    //we exit from the recursion drillDownDependencies and add the file that we have passed
    //if not exists
    if (filesInDependantOrder.indexOf( file ) < 0) {
        filesInDependantOrder.push( file );
    }
}

function drillDownDependencies( root )
{
    //loop through all dependencies of the given file
    for (var i = 0, ilen = root["dep"].length; i < ilen; i++)
    {
        //pass the dependency to check if the given
        //dependency has dependencies by its own
        drillDownDependencies( files[root["dep"][i]] );

        //we exit from the recursion if the dependency
        //don't have other dependencies
        if (filesInDependantOrder.indexOf( root["dep"][i] ) < 0)
        {
            //push the dependency that don't have
            //other dependencies if not exists
            filesInDependantOrder.push( root["dep"][i] );
        }
    }
}

console.log(filesInDependantOrder);

所以问题是:我的解决方案是否完美?在依赖文件之前,它会以某种方式失败吗?我想不出一个会落在他脸上的情景。

- 对于那些会建议我实施AMD(如require.js)的人来说,它不适合我的情况。

1 个答案:

答案 0 :(得分:2)

我认为只要你没有循环依赖,你的解决方案就会有用。

您的信息称为topological sorting。维基页面包含有效执行排序和检测循环依赖关系的算法:

L ← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edges
while S is non-empty do
    remove a node n from S
    add n to tail of L
    for each node m with an edge e from n to m do
        remove edge e from the graph
        if m has no other incoming edges then
            insert m into S
if graph has edges then
    return error (graph has at least one cycle)
else 
    return L (a topologically sorted order)