Skip to content
Advertisement

php sort multidimentional array by custom order

Sorting an multidimensional array by one of its key value (asc or desc) is asked too many times. but I’ve not found any solution for my problem where you have to sort a multidimensional array by one of its key value in predefined custom order.

take an array for example

$array[0] = array('id'=> '111', value=>'abc');
$array[1] = array('id'=> '100', value=>'abc');
$array[2] = array('id'=> '132', value=>'abc');
$array[3] = array('id'=> '222', value=>'abc');
$array[4] = array('id'=> '112', value=>'abc');
$array[5] = array('id'=> '200', value=>'abc');

and to sort this array by subkey ‘id’ by the order defined in array below:

$sort_order_id = array('112','111','132','100');

so the result would be

$array[0] = array('id'=> '112', value=>'abc');
$array[1] = array('id'=> '111', value=>'abc');
$array[2] = array('id'=> '132', value=>'abc');
$array[3] = array('id'=> '100', value=>'abc');
$array[4] = array('id'=> '222', value=>'abc');
$array[5] = array('id'=> '200', value=>'abc');

NOTE: if some of the id’s are not available in $sort_order_id array, keep them in last (like in above example id 222 and 200 are not in $sort_order_id array, so it comes in last as per their previous order)

i tried a lot but unable to create algorithm for that… i hope some one will help me…

Advertisement

Answer

Take the standard code for sorting an array by id:

usort($data, function($x, $y) { return $x['id'] - $y['id']; });

What you want to do is sort not by the ids themselves, but rather by the “weight” of each id (which represents the arbitrary order you want the ids to be put in). So make an array where keys are ids and values are the weights and use it to convert ids to weights:

// array_flip turns 0 => 112, 1 => 111, ... into 122 => 0, 111 => 1, ...
$weights = array_flip(array('112','111','132','100'));

usort($data, function($x, $y) use($weights) {
    return $weights[$x['id']] - $weights[$y['id']];
});

Update: Since you also want to handle ids that do not have a specified weight you will have to further expand the above:

usort($data, function($x, $y) use($weights) {
    if (!isset($weights[$x['id']], $weights[$y['id']])) {
        // none of the ids have weight, so sort by bare id
        return $x['id'] - $y['id'];
    }
    else if (!isset($weights[$x['id']])) { 
        // x does not have weight, put it last
        return 1;
    }
    else if (!isset($weights[$y['id']])) {
        // y does not have weight, put it last
        return -1;
    }

    // both have weights, use them
    return $weights[$x['id']] - $weights[$y['id']];
});
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement