【问题标题】:PHP sorting dependency array list - Topological SortingPHP排序依赖数组列表 - 拓扑排序
【发布时间】:2016-10-21 06:32:40
【问题描述】:

我有一组具有依赖关系的文件。我需要对它们进行排序,以便所有依赖文件在它们的依赖之后被索引。我已经对 forEach 循环和 while 循环进行了很多尝试,但是一旦移动了依赖项,循环就不会考虑以前的迭代并且索引元素会乱序。

我有一个我正在处理的数据的简化版本:

$dependencies = array(
        array(
            'handle'    => 'jquery',
            'requires'  => array(
                'jquery-core',
                'jquery-migrate'
            )
        ),
        array(
            'handle'    => 'jquery-migrate',
            'requires'  => array()
        ),
        array(
            'handle'    => 'common',
            'requires'  => array(
                'utils',
                'jquery',
                'jquery-core',
                'jquery-migrate',
                'jquery-effects-core',
                'backbone'
            )
        ),
        array(
            'handle'    => 'jquery-effects-core',
            'requires'  => array(
                'jquery',
                'jquery-core',
                'jquery-migrate'
            )
        ),
        array(
            'handle'    => 'backbone',
            'requires'  => array(
                'underscore',
                'jquery'
            )
        ),
        array(
            'handle'    => 'underscore',
            'requires'  => array()
        ),
        array(
            'handle'    => 'utils',
            'requires'  => array()
        ),
        array(
            'handle'    => 'jquery-core',
            'requires'  => array()
        )
    );

如果 [handle] 出现在元素 [requires] 数组中,则该元素需要移动到指示的 [requires] 元素之前,同时保持之前考虑的任何其他依赖项。

    function moveEle(&$array, $a, $b){
        $out            = array_splice($array, $a, 1);
        array_splice($array, $b, 0, $out);
    }

    foreach($dependencies as $i=>$dependency){
        if( count($dependency['requires'])>0 ){
            $itr        = count($dependency['requires']);
            echo $dependency['handle']."<br/>";
            while($itr > 0){
                // loop through current files required files
                foreach( $dependency['requires'] as $k=>$dep ){
                    // loop through dependencies array again to find required file handle
                    echo "-- " . $dep . "<br/>";
                    foreach($dependencies as $j=>$jDep){
                        // $j = index in dependencies array of required file, $i = index in dependencies array of dependent file.
                        if( $dep === $jDep['handle'] && $j > $i ){
                            echo "found " . $jDep['handle'] . "@ " . $j."<br/>";
                            moveEle(&$dependencies, $j, $i );
                        }
                    }
                    $itr--;
                }
            }
        }
    }

我认为可能有一些递归方法可以做到这一点,这超出了我目前的技能范围。任何帮助将不胜感激。

我确实找到了这个解决方案: PHP Order array based on elements dependency 这确实有效,但是,一旦数组达到 150 个文件(实际数据大小),它就会超时或花费非常长的时间。我想要一个更有效的解决方案,如果有的话。

【问题讨论】:

    标签: php arrays sorting multidimensional-array


    【解决方案1】:

    嗯,我得到了想要的结果:

    /*
            *
            *   @description        return nested array with all dependencies & sub dependencies
            *
        **/
        function getWithDependencies($dependency, $collection){
            $helper     = new Insight_WP_Scripts_Helpers();
            $set = array(
                'handle'        => $dependency,
                'dependencies'  => array()
            );
    
            foreach($collection as $index=>$data){
                if( $data['handle'] === $set['handle'] ){
                    // echo "<h4>".$data['handle']."</h4>";
                    if(count($helper->getDependencies($set, $collection))>0){
                        $dependencies       = $helper->getDependencies($set['handle'], $collection);
                        foreach($dependencies as $i=>$dependency){
                            // echo $dependency . "<br/>";
                            $set['dependencies'][$i]        = array(
                                'handle'        => $dependency,
                                'dependencies'  => array()
                            );
                            if( count($helper->getDependencies($dependency, $collection)) > 0 ){
                                foreach(getWithDependencies($dependency, $collection) as $k=>$dep){
                                    $set['dependencies'][$i]['dependencies']    = $dep;
                                }
                            }
                        }
                    }
                }
            }
            return $set;
        }
    
        /*
            *
            *   @description        recursively sorts dependencies to depth returned by getWithDependencies()
            *
        **/
        function sortDependency($data,&$collection){
            $helper     = new Insight_WP_Scripts_Helpers();
            foreach($collection as $index=>$inst){
                if( $inst['handle'] === $data['handle'] && count($data['dependencies'])>0){
                    // iterate over each dependency
                    foreach( $inst['dependencies'] as $i=>$dependency ){
                        // iterate over the collection to find dependencies position for comparison against dependent file.
                        foreach( $collection as $k=>$kdep ){
                            if($kdep['handle'] === $dependency['handle'] && $index < $k){
                                $helper->moveArrayElement($collection, $k, $index);
                                // call recursively to search full depth
                                if( count($dependency['dependencies']) > 0 ){
                                    sortDependency($dependency,$collection);
                                }
                            }
                        }
                    }
                }
            }
        }
    
        foreach( $dependencies as $index=>$data ){
            $fullDependencies       = array();
            foreach($dependencies as $i=>$dependency){
                $fullDependencies[]     = getWithDependencies($dependency['handle'], $dependencies);
            }
        }
        $_fullDependencies = $fullDependencies;
        foreach( $fullDependencies as $index=>$data ){
            sortDependency($data,$_fullDependencies);
        }
        $fullDependencies = $_fullDependencies;
    return $fullDependencies;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-28
      • 2014-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      相关资源
      最近更新 更多