Search code examples
phparrayssortingmultidimensional-array

Sort a 2d array by column value and preserve numeric first level keys


I have an array as following and I want to order that array by the value of the key "attack". First keys of the arrays (15, 13, 18) are ID of some certain item from database, so I don't want these keys to be changed when the array is sorted.

This is the array:

$data = array(
    '15' => array(
        'attack' => '45',
        'defence' => '15',
        'total' => '10'
    ),
    '13' => array(
        'attack' => '25',
        'defence' => '15',
        'total' => '10'
    ),
    '18' => array(
        'attack' => '35',
        'defence' => '15',
        'total' => '10'
    )
);

Solution

  • Use uasort():

    This function sorts an array such that array indices maintain their correlation with the array elements they are associated with, using a user-defined comparison function.

    This is used mainly when sorting associative arrays where the actual element order is significant.

    Example:

    function cmp($a, $b) {
        if ($a['attack'] == $b['attack']) {
            return 0;
        }
        return ($a['attack'] < $b['attack']) ? -1 : 1;
    } 
    
    uasort($data, 'cmp');
    

    If the values are always strings, you can also use strcmp() in the cmp() function:

    function cmp($a, $b) {
        return strcmp($a['attack'], $b['attack']);
    } 
    

    Update:

    To sort in descending order you just have to change the return values:

    return ($a['attack'] < $b['attack']) ? 1 : -1;
    //                                     ^----^
    

    or to pick up @salathe's proposal:

    return $b['attack'] - $a['attack'];