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

橡子

我试图从数据库查询中建立一个结果数组,基本上我想知道是否下面的可能

数组内容:

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
        )

)

如果您要对此排序,可以在Section_Position上说,它将返回类似以下内容的内容:

usort($sections, function($a, $b) {
     return $a['section_position'] - $b['section_position'];
});
  1. 第一节
  2. SubSection1ForSection2
  3. SubSection1ForSection1
  4. 第二节

虽然我需要它与各自的孩子一起订购这些部门:

  1. 第一节
  2. SubSection1ForSection1
  3. 第二节
  4. SubSection1ForSection2

我认为不知何故重复问题是思考的方式,但我似乎找不到找到使我成功的方法。

有没有办法做到这一点,或者我必须使用forloop-gets进行变通,以便首先获取深度1的所有值,然后使用节的名称获取深度2的所有值,依此类推?

(对不起我的英语不好。)

鳕鱼

好的,这可能是一个丑陋的解决方案,但是如果将所有内容都放在一个函数中,它看起来就不错了:)。好消息是它将在您的方案中起作用。

码:

$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
        )

)

注意:首先要按照父母的Section_Position进行排序,然后再按照孩子的Section_Position进行排序

更新

首先,我想对主持人与@Akorna进行的漫长的讨论表示抱歉,但我需要给他这段代码,我认为它将在将来发挥作用。因此,@ Akorna应该适合您的代码是以下代码:

$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;

我确实从输入数据中删除了一些东西,以便可以定位自己。只需尝试将输入数据提供给逻辑,然后让我知道结果是什么。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章