Search code examples
phparrayssortingmultidimensional-arrayassociative-array

Sort a 2d array by a column without preserving the first level keys


I'm trying to sort this associative array in PHP, sorting by field name

$fonts = array(
    0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
    1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
    2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
    3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
);

What I'm trying to do is to sort the entries by name but keep the keys associated with the entry itself, so what I want is:

 $fonts = array(
    3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
    0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
    2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
    1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
);

Here's the bare minimum code which exposes the problem (PHP ver +7):

function cmp($a, $b)
{
    return strcmp($a["name"], $b["name"]);
}

$fonts = array(
    0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
    1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
    2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
    3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
);

uasort($fonts, "cmp");

for($i = 0; $i < 4; $i++)
{
    echo "<br/>".$fonts[$i]["name"];
}

I'm using uasort() as it's supposed to keep the keys associated while sorting the array. Unfortunately if I print the array I get the same order, that is:

Arial
Times
Roboto
AlexBrush

Solution

  • Do sort by name like this way and loop using foreach()

    <?php
    
    $fonts = array(
        0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
        1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
        2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
        3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
    );
    
    uasort($fonts, function($a, $b) {
        return strcmp($a['name'], $b['name']);
    });
    
    print_r($fonts);
    
    foreach($fonts as $font){
     echo $font["name"].PHP_EOL;
    }
    
    ?>
    

    EDIT: Based on OP's comment,

     $indexed_array = array_column($fonts,'name','index'); // array column map name by index
     print_r($indexed_array); 
     echo $indexed_array[3];
    

    DEMO: https://3v4l.org/W7BOH