按父级排序的PHP数组

时间:2013-12-22 13:34:37

标签: php arrays sorting

我有一个要排序的复杂数组,它看起来像这样:

Array
(
    [0] => Array
        (
            [id] => 1171409310
            [parent] => 1171287657
            [createdAt] => 2013-12-20T12:42:19
        )

    [1] => Array
        (
            [id] => 1171360372
            [parent] => 1171313704
            [createdAt] => 2013-12-20T11:18:46
        )

    [2] => Array
        (
            [id] => 1171313704
            [parent] => 1171304353
            [createdAt] => 2013-12-20T10:14:46
        )

    [3] => Array
        (
            [id] => 1171304353
            [parent] => 1171287657
            [createdAt] => 2013-12-20T09:55:34
        )

    [4] => Array
        (
            [id] => 1171303539
            [parent] => 1171014482
            [createdAt] => 2013-12-20T09:53:54
        )

    [5] => Array
        (
            [id] => 1171287657
            [parent] => 1170597579
            [createdAt] => 2013-12-20T09:29:34
        )

    [6] => Array
        (
            [id] => 1171264520
            [parent] => 1169354287
            [createdAt] => 2013-12-20T08:58:26
        )

    [7] => Array
        (
            [id] => 1171014482
            [parent] => 
            [createdAt] => 2013-12-20T02:51:24
        )

    [8] => Array
        (
            [id] => 1170700661
            [parent] => 1170597579
            [createdAt] => 2013-12-19T21:30:31
        )

    [9] => Array
        (
            [id] => 1170597579
            [parent] => 
            [createdAt] => 2013-12-19T20:22:40
        )

    [10] => Array
        (
            [id] => 1169362457
            [parent] => 
            [createdAt] => 2013-12-18T22:27:28
        )

    [11] => Array
        (
            [id] => 1169354287
            [parent] => 
            [createdAt] => 2013-12-18T22:20:08
        )

    [12] => Array
        (
            [id] => 1169315244
            [parent] => 
            [createdAt] => 2013-12-18T21:52:59
        )

)

我希望数组首先按日期排序(最旧的在顶部),然后每个子节点在其父节点之后(最顶层的节点也是如此)。问题是孩子也可能是有孩子的父母,因此有多个维度。如果可能,我还想添加尺寸。

我希望我的问题很明确。

编辑:我从disqus API获取数组,并希望它像在网站上一样排序。

编辑:它必须像这样结束:

Array
(
    [12] => Array
        (
            [id] => 1169315244
            [parent] => 
            [createdAt] => 2013-12-18T21:52:59
        )

    [11] => Array
        (
            [id] => 1169354287
            [parent] => 
            [createdAt] => 2013-12-18T22:20:08
        )

    [6] => Array
        (
            [id] => 1171264520
            [parent] => 1169354287
            [createdAt] => 2013-12-20T08:58:26
        )

    [10] => Array
        (
            [id] => 1169362457
            [parent] => 
            [createdAt] => 2013-12-18T22:27:28
        )

    [9] => Array
        (
            [id] => 1170597579
            [parent] => 
            [createdAt] => 2013-12-19T20:22:40
        )

    [8] => Array
        (
            [id] => 1170700661
            [parent] => 1170597579
            [createdAt] => 2013-12-19T21:30:31
        )

    [5] => Array
        (
            [id] => 1171287657
            [parent] => 1170597579
            [createdAt] => 2013-12-20T09:29:34
        )

    [3] => Array
        (
            [id] => 1171304353
            [parent] => 1171287657
            [createdAt] => 2013-12-20T09:55:34
        )

    [2] => Array
        (
            [id] => 1171313704
            [parent] => 1171304353
            [createdAt] => 2013-12-20T10:14:46
        )

    [1] => Array
        (
            [id] => 1171360372
            [parent] => 1171313704
            [createdAt] => 2013-12-20T11:18:46
        )

    [0] => Array
        (
            [id] => 1171409310
            [parent] => 1171287657
            [createdAt] => 2013-12-20T12:42:19
        )

    [7] => Array
        (
            [id] => 1171014482
            [parent] => 
            [createdAt] => 2013-12-20T02:51:24
        )


    [4] => Array
        (
            [id] => 1171303539
            [parent] => 1171014482
            [createdAt] => 2013-12-20T09:53:54
        )

)

3 个答案:

答案 0 :(得分:3)

我现在正在建立一个评论系统。只是订购这样的评论并不能真正让你在评论(亲子关系)之间建立牢固的关系。

在这种情况下,我会执行以下操作:

$comments = array();
foreach ($results as $result) {
    if ($result["parent"]) {
        $result["children"] = array();
        $comments[$result["id"]] = $result;
    }
}

// Have yet to do this a better way. Second loop is there for a reason.
foreach ($results as $result) {
    if ($result["parent"])
        $comments[$result["parent"]]["children"] = $result;
}

var_dump($comments);
// you can now sort on createdAt using uasort(array $array, callable $func)

uasort($comments, function ($a, $b) {
    if ($a["createdAt"] == $b["createdAt"])
        return 0;
    return ($a["createdAt"] > $b["createdAt"]) ? 1 : -1;
    // reverse this to change sort order
});

答案 1 :(得分:2)

uasort($array, function($a, $b) {   
    // sort by date first
    if (@$a["createdAt"] == @$b["createdAt"]){
        return 0;
    }
    return (@$a["createdAt"] > @$b["createdAt"]) ? 1 : -1;
});
$array_asc = array();
foreach($array as $key => $val){ 
    // create an array with ids as keys and children
    // with the assumption that parents are created earlier. 
    // store the original key
    $array_asc[$val['id']] = array_merge($val, array('org_key' => $key)); 
    if ($val['parent']){
        $array_asc[$val['parent']]['children'][] = $val['id'];
    }
}
$array_out = array();

// get a flat array again

foreach($array_asc as $val){
    if ($val['parent']){
        continue;         
    }
    add_to_output($array_out, $val, $array_asc);
}

function add_to_output(&$array_out, $val, $array_asc){ 
    $array_out[$val['org_key']] = $val;
    if (sizeof($val['children'])){
        foreach($val['children'] as $id){
            add_to_output($array_out, $array_asc[$id], $array_asc);
        }
    }
    unset($array_out[$val['org_key']]['children'], $array_out[$val['org_key']]['org_key']);
}

未经测试。

答案 2 :(得分:1)

您可以使用php array_multisort

你可能想要像这样构建你的数组

<?php
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);
}
?>


<?php
$data[] = array('createdAt' => 67, 'parent' => 2);
$data[] = array('createdAt' => 86, 'parent' => 1);
$data[] = array('createdAt' => 85, 'parent' => 6);
$data[] = array('createdAt' => 98, 'parent' => 2);
$data[] = array('createdAt' => 86, 'parent' => 6);
$data[] = array('createdAt' => 67, 'parent' => 7);

// Pass the array, followed by the column names and sort flags
$sorted = array_orderby($name_of_array, 'createdAt', SORT_DESC, 'parent', SORT_ASC);
?>