3

I got a complex array to be sorted, it looks like this:

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
        )

)

I want the array to be first sorted by date (oldest on the top) and then each child after its parent (oldest on the top as well). The problem is that children can also be parents who have children as well so there are multiple dimensions. If possible I want also add the dimension.

I hope that my problem is clear.

EDIT: I get the array from the disqus API and want it to be sorted like it is on a website.

EDIT: It has to end like this:

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 Answers 3

3

I'm building a comment system myself, currently. Just ordering the comments like this is not going to really give you a strong relationship between comments (a parent-child relationship).

In this case, I'd do the following:

$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
});
Sign up to request clarification or add additional context in comments.

3 Comments

@oskar and they will be deemed equal since null == null. also i didnt finish reading the question. adding the other sort
@oskar you're relying on a loose relationship to have a comment hierarchy. I'm currently doing a comment system in PHP myself, so I'll just show you how I've done it.
yeah, i am trying to integrate disqus into an app, unfortunately the order is still not right...
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']);
}

not tested.

1 Comment

after correcting some syntax errors its working perfectly, thanks!!
1

you can user the php array_multisort

you probably want to build your array like this

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

6 Comments

I receive the array from the disqus API and want to sort it like its sorted on a website.
@Oskar This will work to sort your array, i just tried it. I don't know why you are voting down on this
It's a horribly complicated answer to sorting a simple array (that array is by no means complicated).
but it works and that code can be reuse to sort any array that he/she has. instead of creating a new function for each array.
What is the order that you are getting now?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.