【问题标题】:PHP Order array based on elements dependency基于元素依赖的PHP Order数组
【发布时间】:2017-02-04 07:43:00
【问题描述】:

很难解释,但实际上我有一组具有 ID 的项,其中可以包含其他数组项的 ID 列表。例如

$items = [
   [id: 'one', deps: ['three']],
   [id: 'two'],
   [id: 'three', deps: ['four', 'two']],
   [id: 'four']
];

所以你可以在这里看到,一取决于三,三取决于四和二。

我需要得到一个新数组,它按顺序包含这些项目 - 以便按顺序列出依赖项。所以上面的数组会转换成

$items = [
   [id: 'four'],
   [id: 'two'],
   [id: 'three', deps: ['four', 'two']],
   [id: 'one', deps: ['three']]
];

我将如何完成这项工作?我尝试了各种 while 循环检查项目位置,但无法破解它。

谢谢

更新有人说这是THIS的重复问题,但主要区别是上面的例子有多个依赖项——而提到的线程只适用于单个字符串依赖项

【问题讨论】:

    标签: php arrays sorting dependencies


    【解决方案1】:

    您可以使用这样的函数,它会迭代直到满足所有依赖项,或者无法解析更多依赖项:

    $items = array(array('id' => 'one', 'deps' => array('three')),
                    array('id' => 'two'),
                    array('id' => 'three', 'deps' => array('four', 'two')),
                    array('id' =>'four'));
    
    
    $sortedItems = sortDeps($items);
    var_dump($sortedItems);
    
    function sortDeps($items) {
        $res = array();
        $doneList = array();
    
        // while not all items are resolved:
        while(count($items) > count($res)) {
            $doneSomething = false;
    
            foreach($items as $itemIndex => $item) {
                if(isset($doneList[$item['id']])) {
                    // item already in resultset
                    continue;
                }
                $resolved = true;
    
                if(isset($item['deps'])) {
                    foreach($item['deps'] as $dep) {
                        if(!isset($doneList[$dep])) {
                            // there is a dependency that is not met:
                            $resolved = false;
                            break;
                        }
                    }
                }
                if($resolved) {
                    //all dependencies are met:
                    $doneList[$item['id']] = true;
                    $res[] = $item;
                    $doneSomething = true;
                }
            }
            if(!$doneSomething) {
                echo 'unresolvable dependency';
            }
        }
        return $res;
    }
    

    【讨论】:

    • @andrew 这工作完美(几乎):P 我必须添加 $items = array_unique($items, SORT_REGULAR); 以防某些项目在列表中被请求了两次!
    • 我没有对其进行太多测试,但看起来像是一个可行的解决方案,并且只有 2 个循环!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 2010-09-29
    • 2015-11-03
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    相关资源
    最近更新 更多