在PHP中使用多个条件对多维数组排序

在PHP中使用多个条件对多维数组排序,php,arrays,sorting,multidimensional-array,Php,Arrays,Sorting,Multidimensional Array,我正试图从一个DB查询中建立一个结果数组,基本上我想知道下面的方法是否可行 数组内容: Array ( [0] => Array ( [Section_Id] => 1 [Section_Name] => "Section1" [Section_Parent] => NULL [Section_Position] => 0

我正试图从一个DB查询中建立一个结果数组,基本上我想知道下面的方法是否可行

数组内容:

Array
(
    [0] => Array
        (
            [Section_Id] => 1
            [Section_Name] => "Section1"
            [Section_Parent] => NULL
            [Section_Position] => 0
            [Section_Depth] => 0
        )

    [1] => Array
        (
            [Section_Id] => 3
            [Section_Name] => "Section2"
            [Section_Parent] => NULL
            [Section_Position] => 1
            [Section_Depth] => 0

        )

    [2] => Array
        (
            [Section_Id] => 4
            [Section_Name] => "SubSection1ForSection2"
            [Section_Parent] => 3
            [Section_Position] => 0
            [Section_Depth] => 1
        )

    [3] => Array
        (
            [Section_Id] => 2
            [Section_Name] => "SubSection1ForSection1"
            [Section_Parent] => 1
            [Section_Position] => 0
            [Section_Depth] => 1
        )

)
如果您要对这一个进行排序,让我们假设在第_节位置,它将返回如下内容:

usort($sections, function($a, $b) {
     return $a['section_position'] - $b['section_position'];
});
  • 第一节
  • 第1小节第2小节
  • 第1节第1节
  • 第2节
  • 我需要它来订购各部分及其各自的孩子:

  • 第一节
  • 第1节第1节
  • 第2节
  • 第1小节第2小节
  • 我认为这是一种思考的方式,但我似乎找不到一种方法来让这一切对我有用

    有没有办法做到这一点,或者我必须用forloop get做一个变通方法,以便首先获取depth 1的所有值,然后使用节的名称获取depth 2的所有值,依此类推


    (对不起我的英语。)

    好的,这可能是一个丑陋的解决方案,但如果你把所有东西都放在一个函数中,它看起来很好:)。好的是,它将在您的场景中工作

    代码:

    注意:第一个排序是根据父节位置进行排序,然后根据子节位置进行排序

    U p D A T E

    首先,我想对主持人说声抱歉,因为我们与@Akorna进行了长时间的讨论,但我需要给他这个代码,我认为这将在未来起到作用。因此@Akorna应该适用于您的代码如下:

    $inputData=数组(
    排列(
    “截面id”=>333,
    “截面深度”=>1,
    “节_父项”=>332,
    “截面位置”=>0,
    “章节标题”=>“引言”),
    排列(
    “节号”=>334,
    “截面深度”=>1,
    “节_父项”=>332,
    “截面位置”=>1,
    “章节标题”=>“词汇表”),
    排列(
    “截面id”=>335,
    “截面深度”=>1,
    “节_父项”=>332,
    “截面位置”=>2,
    '部分标题'=>'命令'),
    排列(
    “截面id”=>336,
    “截面深度”=>1,
    “节_父项”=>332,
    “截面位置”=>3,
    “部分标题”=>“组件”),
    排列(
    “截面id”=>337,
    “截面深度”=>2,
    “节_父项”=>336,
    “截面位置”=>0,
    “章节标题”=>“引言”),
    排列(
    “截面id”=>407,
    “截面深度”=>2,
    “section_parent”=>401,
    “截面位置”=>2,
    “部分标题”=>“Web应用程序”),
    排列(
    “截面id”=>338,
    “截面深度”=>2,
    “节_父项”=>336,
    “截面位置”=>1,
    “section_title'=>“AbstractContainer”),
    排列(
    “截面id”=>406,
    “截面深度”=>2,
    “section_parent”=>401,
    “截面位置”=>1,
    “部分标题”=>“Web应用程序”),
    排列(
    “截面id”=>339,
    “截面深度”=>2,
    “节_父项”=>336,
    “截面位置”=>2,
    “部分标题”=>“操作容器”),
    排列(
    “截面id”=>340,
    “截面深度”=>2,
    “节_父项”=>336,
    “截面位置”=>3,
    “章节标题”=>“浏览器不兼容”),
    排列(
    “截面id”=>404,
    “截面深度”=>2,
    “节_父项”=>402,
    “截面位置”=>3,
    “部分标题”=>“Web应用程序”),
    排列(
    “截面id”=>341,
    “截面深度”=>2,
    “节_父项”=>336,
    “截面位置”=>4,
    “节标题”=>“可折叠容器”),
    排列(
    “截面id”=>342,
    “截面深度”=>2,
    “节_父项”=>336,
    “截面位置”=>5,
    “章节标题”=>“详细信息容器”),
    排列(
    “截面id”=>343,
    “截面深度”=>2,
    “节_父项”=>336,
    “截面位置”=>6,
    “部分标题”=>“动态菜单”),
    排列(
    “节号”=>403,
    “截面深度”=>2,
    “节_父项”=>402,
    “截面位置”=>1,
    “部分标题”=>“Web应用程序”),
    排列(
    “截面id”=>344,
    “截面深度”=>2,
    “节_父项”=>336,
    “截面位置”=>7,
    “部分标题”=>“设置”),
    排列(
    “截面id”=>345,
    “截面深度”=>2,
    “节_父项”=>336,
    “截面位置”=>8,
    “章节标题”=>“子文件视图”),
    排列(
    “截面id”=>346,
    “截面深度”=>2,
    “节_父项”=>336,
    “截面位置”=>9,
    “章节标题”=>“分类管理”),
    排列(
    “截面id”=>402,
    “截面深度”=>1,
    “节_父项”=>400,
    “截面位置”=>2,
    “部分标题”=>“Web应用程序”),
    排列(
    '截面id'=>401,
    “截面深度”=>1,
    “节_父项”=>400,
    “截面位置”=>1,
    “部分标题”=>“Web应用程序”),
    排列(
    “截面id”=>347,
    “截面深度”=>2,
    “节_父项”=>336,
    “截面位置”=>10,
    “section_title'=>“UploadQueue”),
    排列(
    “截面id”=>400,
    “截面深度”=>0,
    “section_parent”=>null,
    “截面位置”=>5,
    “部分标题”=>“Web应用程序”),
    排列(
    “截面id”=>332,
    “截面深度”=>0,
    “section_parent”=>null,
    “截面位置”=>3,
    '部分标题'=>'Web应用程序')
    );
    /*先按截面深度排序,然后按截面位置排序*/
    $inputData=array\u orderby($inputData,'section\u depth',SORT\u ASC,'section\u position',SORT\u ASC);
    $parents=array();
    $sortedByParent=false;
    而(!$sortedByParent){
    $elems=阵列拼接($inputData,count($inputDat
    
    $inputData = array(
        array(
            'Section_Id' => 1,
            'Section_Name' => "Section1",
            'Section_Parent' => NULL,
            'Section_Position' => 1,
            'Section_Depth' => 0,
        ),
        array(
            'Section_Id' => 2,
            'Section_Name' => "Section2",
            'Section_Parent' => NULL,
            'Section_Position' => 0,
            'Section_Depth' => 0
        ),
        array(
            'Section_Id' => 4,
            'Section_Name' => "SubSection2ForSection2",
            'Section_Parent' => 2,
            'Section_Position' => 1,
            'Section_Depth' => 1
        ),
        array(
            'Section_Id' => 5,
            'Section_Name' => "SubSection1ForSection2",
            'Section_Parent' => 2,
            'Section_Position' => 0,
            'Section_Depth' => 1
        ),
        array(
            'Section_Id' => 3,
            'Section_Name' => "SubSection1ForSection1",
            'Section_Parent' => 1,
            'Section_Position' => 0,
            'Section_Depth' => 1
        )
    );
    
    
    $parentRecords = array();
    $childRecords = array();
    $sorted = array();
    
    /* split in two collections */
    foreach ($inputData as $sectionData) {
        if (is_null($sectionData['Section_Parent'])) {
            /* assume this is a parent */
            $parentRecords[] = $sectionData;
        } else {
            /* assume we are on child row */
            $childRecords[] = $sectionData;
        }
    }
    
    /* now first order parents by Section_Position */
    usort($parentRecords, function($a, $b) {
    
            if ($a['Section_Position'] == $b['Section_Position']) {
                return 0;
            }
            return $a['Section_Position'] > $b['Section_Position'] ? 1 : -1;
        });
    
    /* now the actual sorting */
    foreach ($parentRecords as $parentData) {
        $parentId = $parentData['Section_Id'];
        /* now get all children of this parent */
        $parentChildren = array();
        foreach ($childRecords as $childData) {
            if ($childData['Section_Parent'] == $parentId) {
                $parentChildren[] = $childData;
            }
        }
    
        /* now sort the children by Section_Position */
        usort($parentChildren, function($a, $b) {
    
            if ($a['Section_Position'] == $b['Section_Position']) {
                return 0;
            }
            return $a['Section_Position'] > $b['Section_Position'] ? 1 : -1;
        });
    
        $sorted[] = $parentData;
        $sorted = array_merge($sorted, $parentChildren);
    }
    
    
    echo '<pre>' . print_r($sorted, true) . '</pre>';
    exit;
    
    Array
    (
        [0] => Array
            (
                [Section_Id] => 2
                [Section_Name] => Section2
                [Section_Parent] => 
                [Section_Position] => 0
                [Section_Depth] => 0
            )
    
        [1] => Array
            (
                [Section_Id] => 5
                [Section_Name] => SubSection1ForSection2
                [Section_Parent] => 2
                [Section_Position] => 0
                [Section_Depth] => 1
            )
    
        [2] => Array
            (
                [Section_Id] => 4
                [Section_Name] => SubSection2ForSection2
                [Section_Parent] => 2
                [Section_Position] => 1
                [Section_Depth] => 1
            )
    
        [3] => Array
            (
                [Section_Id] => 1
                [Section_Name] => Section1
                [Section_Parent] => 
                [Section_Position] => 1
                [Section_Depth] => 0
            )
    
        [4] => Array
            (
                [Section_Id] => 3
                [Section_Name] => SubSection1ForSection1
                [Section_Parent] => 1
                [Section_Position] => 0
                [Section_Depth] => 1
            )
    
    )
    
    $inputData = array(
        array(
            'section_id' => 333,
            'section_depth' => 1,
            'section_parent' => 332,
            'section_position' => 0,
            'section_title' => 'Introduction'),
        array(
            'section_id' => 334,
            'section_depth' => 1,
            'section_parent' => 332,
            'section_position' => 1,
            'section_title' => 'Glossary'),
        array(
            'section_id' => 335,
            'section_depth' => 1,
            'section_parent' => 332,
            'section_position' => 2,
            'section_title' => 'Commands'),
        array(
            'section_id' => 336,
            'section_depth' => 1,
            'section_parent' => 332,
            'section_position' => 3,
            'section_title' => 'Components'),
        array(
            'section_id' => 337,
            'section_depth' => 2,
            'section_parent' => 336,
            'section_position' => 0,
            'section_title' => 'Introduction'),
        array(
            'section_id' => 407,
            'section_depth' => 2,
            'section_parent' => 401,
            'section_position' => 2,
            'section_title' => 'Web Application'),
        array(
            'section_id' => 338,
            'section_depth' => 2,
            'section_parent' => 336,
            'section_position' => 1,
            'section_title' => 'AbstractContainer'),
        array(
            'section_id' => 406,
            'section_depth' => 2,
            'section_parent' => 401,
            'section_position' => 1,
            'section_title' => 'Web Application'),
        array(
            'section_id' => 339,
            'section_depth' => 2,
            'section_parent' => 336,
            'section_position' => 2,
            'section_title' => 'ActionsContainer'),
        array(
            'section_id' => 340,
            'section_depth' => 2,
            'section_parent' => 336,
            'section_position' => 3,
            'section_title' => 'BrowserIncompatibility'),
        array(
            'section_id' => 404,
            'section_depth' => 2,
            'section_parent' => 402,
            'section_position' => 3,
            'section_title' => 'Web Application'),
        array(
            'section_id' => 341,
            'section_depth' => 2,
            'section_parent' => 336,
            'section_position' => 4,
            'section_title' => 'CollapsibleContainer'),
        array(
            'section_id' => 342,
            'section_depth' => 2,
            'section_parent' => 336,
            'section_position' => 5,
            'section_title' => 'DetailsContainer'),
        array(
            'section_id' => 343,
            'section_depth' => 2,
            'section_parent' => 336,
            'section_position' => 6,
            'section_title' => 'DynamicMenu'),
        array(
            'section_id' => 403,
            'section_depth' => 2,
            'section_parent' => 402,
            'section_position' => 1,
            'section_title' => 'Web Application'),
        array(
            'section_id' => 344,
            'section_depth' => 2,
            'section_parent' => 336,
            'section_position' => 7,
            'section_title' => 'Settings'),
        array(
            'section_id' => 345,
            'section_depth' => 2,
            'section_parent' => 336,
            'section_position' => 8,
            'section_title' => 'SubfilesViewer'),
        array(
            'section_id' => 346,
            'section_depth' => 2,
            'section_parent' => 336,
            'section_position' => 9,
            'section_title' => 'Taxonomy Management'),
        array(
            'section_id' => 402,
            'section_depth' => 1,
            'section_parent' => 400,
            'section_position' => 2,
            'section_title' => 'Web Application'),
        array(
            'section_id' => 401,
            'section_depth' => 1,
            'section_parent' => 400,
            'section_position' => 1,
            'section_title' => 'Web Application'),
        array(
            'section_id' => 347,
            'section_depth' => 2,
            'section_parent' => 336,
            'section_position' => 10,
            'section_title' => 'UploadQueue'),
        array(
            'section_id' => 400,
            'section_depth' => 0,
            'section_parent' => null,
            'section_position' => 5,
            'section_title' => 'Web Application'),
        array(
            'section_id' => 332,
            'section_depth' => 0,
            'section_parent' => null,
            'section_position' => 3,
            'section_title' => 'Web Application')
    );
    
    /* first order by section_depth and then by section_position */
    $inputData = array_orderby($inputData, 'section_depth', SORT_ASC, 'section_position', SORT_ASC);
    
    $parents = array();
    $sortedByParent = false;
    while (!$sortedByParent) {
        $elems = array_splice($inputData, count($inputData) - 1, 1);
        if (!count($elems)) {
            $sortedByParent = true;
            $inputData = array_merge($inputData, $parents);
            continue;
        }
    
        $elem = $elems[0];
    
        if ($elem['section_depth'] == 0) {
            if (!isset($elem['children'])) {
                $elem['children'] = array();
            }
            $parents[] = $elem;
        } else {
            $inputData = put_in_parent($elem, $inputData);
        }
    }
    
    /* now we have $inputData in nice format like
     * parent(child, child, child(child, child(child, child)), child(child(child(child)))),
     * parent(child, child, child(child, child(child, child)), child(child(child(child))))
     *  */
    $inputData = merge_children_recursively(array_reverse($inputData));
    
    function merge_children_recursively($inputData) {
        $children = array();
        foreach ($inputData as $row) {
            if (isset($row['children'])) {
                /* this ksort call is necessary because the key is actually section_position */
                ksort($row['children']);
                $rowCopy = $row;
                unset($rowCopy['children']);
                $children[] = $rowCopy;
                $children = array_merge($children, merge_children_recursively($row['children']));
            } else {
                $children[] = $row;
            }
        }
    
        return $children;
    }
    
    function put_in_parent($elem, $inputData) {
        foreach ($inputData as $k => $row) {
            if ($row['section_id'] == $elem['section_parent']) {
                if (!isset($inputData[$k]['children'])) {
                    $inputData[$k]['children'] = array();
                }
    
                $inputData[$k]['children'][$elem['section_position']] = $elem;
                break;
            }
        }
        return $inputData;
    }
    
    function array_orderby() {
        $args = func_get_args();
        $data = array_shift($args);
        foreach ($args as $n => $field) {
            if (is_string($field)) {
                $tmp = array();
                foreach ($data as $key => $row) {
                    $tmp[$key] = $row[$field];
                }
                $args[$n] = $tmp;
            }
        }
        $args[] = &$data;
        call_user_func_array('array_multisort', $args);
        return array_pop($args);
    }
    
    echo '<pre>' . print_r($inputData, true) . '</pre>';
    exit;