user3712320
user3712320

Reputation: 116

Sorting Multidimensional array of more than one level

I already checked other question regarding sort multidimensional array but none of them worked in my case my array is as following and i want sort on based of id value in descending order

$arr = array(
49 => array(
    'id' => 65,
    'name' => 'any',
    'users' => array(
        772 => array(
            'id' => 149,
            'name' => 'any1'
        ),
        771 => array(
            'id' => 779,
            'name' => 'any2'
        ),
        45 => array(
            'id' => 259,
            'name' => 'any3'
        )   
    )
),
789 => array(
    'id' => 892,
    'name' => 'any4',
    'users' => array(
        65 => array(
            'id' => 389,
            'name' => 'any5' 
        ),
        98 => array(
            'id' => 895,
            'name' => 'any6'
            ),
        99 => array(
            'id' => 899,
            'name' => 'any7'
        )

    )
)

);

I tried to sort using usort function

usort($arr, function($a, $b) {
return $b['id'] - $a['id'];

});

But my requirement is to sort parent as well as child array but this sort only parents

Upvotes: 0

Views: 63

Answers (2)

Fred Koschara
Fred Koschara

Reputation: 355

Try this:

function myCallback($left,$right)
{
    return $right['id'] - $left['id'];
}

function id_sort(&$array)
{
    if (!is_array($array))
        return;
    foreach ($array as &$elem)
        if (array_key_exists('users',$elem))
            id_sort($elem['users']);
    uasort($array,'myCallback');
}

id_sort($arr);

This sorts parents by id in descending order, and children within those parents in descending order, recursively.

Upvotes: 0

Jonathan Kuhn
Jonathan Kuhn

Reputation: 15301

Since the rules for sorting are the same for both parents and children I just defined a compare function. You just need to loop over each parent and sort the children.

//compare function, sorts by id in desc order
function cmp($a, $b){
    return $b['id'] - $a['id'];
}

//loop over each parent by reference so it changes the value in the parent array    
foreach($arr as &$parent){
    //sort the children
    uasort($parent['users'], 'cmp');
}
//unset the parent array so we don't overwrite the last parent later
unset($parent);

//sort the parents
uasort($arr, 'cmp');

Demo: http://codepad.viper-7.com/hqM122

Edit: added requirement of preserving keys. Just switched usort to uasort.

Upvotes: 1

Related Questions