1

Is there a more compact way to sort an array by two parameters/fields with PHP ≥7.0 (using the spaceship operator <=>) ?

Right now I just to the trick to sort is first by the second parameter and then by the first:

// Sort by second parameter title
usort($products, function ($a, $b) {
    return $a['title'] <=> $b['title']; // string
});

// Sort by first parameter brand_order
usort($products, function ($a, $b) {
    return $a['brand_order'] <=> $b['brand_order']; // numeric
});

This gives me the result I want; the products a first ordered by brand and then by their title.

I just wonder if their is a way to do it one usort call.


Here my questoin as code snippet. This example can be tested here.

<?php
        
// Example array
$products = array();

$products[] = array("title" => "Title A",  
              "brand_name" => "Brand B",
              "brand_order" => 1);
$products[] = array("title" => "Title C",  
              "brand_name" => "Brand A",
              "brand_order" => 0);
$products[] = array("title" => "Title E",  
              "brand_name" => "Brand A",
              "brand_order" => 0);
$products[] = array("title" => "Title D",  
              "brand_name" => "Brand B",
              "brand_order" => 1);

// Sort by second parameter title
usort($products, function ($a, $b) {
    return $a['title'] <=> $b['title']; // string
});

// Sort by first parameter brand_order
usort($products, function ($a, $b) {
    return $a['brand_order'] <=> $b['brand_order']; // numeric
});

// Output
foreach( $products as $value ){
    echo $value['brand_name']." — ".$value['title']."\n";
}

?>
wittich
  • 1,661
  • 1
  • 18
  • 37
  • 1
    `return $a['brand_order'] <=> $b['brand_order'] ?: $a['title'] <=> $b['title']` – What you're doing isn't guaranteed to work, since sorts aren't guaranteed to be stable. – deceze Mar 05 '19 at 13:38
  • @deceze this question was specific about php7 and the spaceship operator, I think this hasn't been explicit answered in the other answers... – wittich Mar 05 '19 at 14:27
  • The spaceship operator doesn't make this question unique. The unique part is the comparison by two separate conditions. And in fact, both topics are discussed in the duplicate. Perhaps not in exactly this combination, but certainly close enough that you can assemble the information into code that fits specifically your situation. – deceze Mar 05 '19 at 14:29
  • 1
    https://blog.martinhujer.cz/clever-way-to-sort-php-arrays-by-multiple-values/ – PHPst Oct 10 '20 at 21:51

1 Answers1

3

usort($products, function ($a, $b) {
    if ( $a['brand_order'] == $b["brand_order"] ) {  //brand_order are same
       return $a['title'] <=> $b['title']; //sort by title
    }
    return $a['brand_order'] <=> $b['brand_order']; //else sort by brand_order
});

Test here

Pavel Třupek
  • 591
  • 4
  • 17
  • Thanks, that's what I was looking for. And now where I read your code, its pretty logically too. – wittich Mar 05 '19 at 13:58