How to usort an array by two parameters using spaceship operator with PHP >=7.0 [duplicate]
Asked Answered
F

1

6

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 there is a way to do it one usort call.


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

<pre><?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";
}

?></pre>

Similar question but not specific about php7 and the spaceship operator have been answered here:

Flooded answered 3/3, 2019 at 11:55 Comment(4)
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.Thynne
@Thynne this question was specific about php7 and the spaceship operator, I think this hasn't been explicit answered in the other answers...Flooded
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.Thynne
blog.martinhujer.cz/…Awn
R
10
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

Runthrough answered 5/3, 2019 at 13:26 Comment(1)
Thanks, that's what I was looking for. And now where I read your code, its pretty logically too.Flooded

© 2022 - 2024 — McMap. All rights reserved.