0

I would like to sort the array below using PHP. The main problem is that I need to sort the array based on multiple criteria:

  • first show the websites with a price
  • if the price is the same, sort them alphabetically
  • if multiple sites have no price, sort them alphabetically

So this array

array(
    [Beslist.nl] => Array
        (
            [price] => 141,63
        )

    [Wehkamp.nl] => Array
        (
            [price] => none
        )

    [Bol.com] => Array
        (
            [price] => none
        )

    [Zalando.nl] => Array
        (
            [price] => none
        )

    [Webwinkel.nl] => Array
        (
            [price] => none
        )

    [Overig.nl] => Array
        (
            [price] => none
        )
)

Should be sorted like this:

array(
    [Beslist.nl] => Array
        (
            [price] => 141,63
        )

    [Bol.com] => Array
        (
            [price] => none
        )

    [Overig.nl] => Array
        (
            [price] => none
        )

    [Webwinkel.nl] => Array
        (
            [price] => none
        )

    [Wehkamp.nl] => Array
        (
            [price] => none
        )

    [Zalando.nl] => Array
        (
            [price] => none
        )

)

I tried asort and ksort, but I need to sort based on multiple criteria, which makes it more complex. I was hoping I could sort the records using SQL (when I read the records from the database). However, the price needs to be calculated afterwards; that is why I need to use PHP.

Anyone who can help me out?

Mario Cervera
  • 641
  • 1
  • 8
  • 19
Erik van de Ven
  • 3,978
  • 4
  • 27
  • 68
  • Are you on Stack Overflow, that someone has to copy&paste your title into google and get the answer in the first result ? – Rizier123 Sep 10 '15 at 14:17
  • 3
    Look up PHP's [`usort()` function](http://php.net/manual/en/function.usort.php). – Simba Sep 10 '15 at 14:17
  • Have you read [Reference: all basic ways to sort arrays and data in PHP](http://stackoverflow.com/a/17364128/476)? – I'd close this as duplicate immediately, but I'll give you that there's a tiny bit of a twist in how your data structure look like. – deceze Sep 10 '15 at 14:17
  • 1
    @Simba With `usort()` OP will lose his keys (For all these who upVoted your comment and don't know what it does) – Rizier123 Sep 10 '15 at 14:18
  • 1
    @Rizier123 Agreed he should use `uasort()` – Daan Sep 10 '15 at 14:24
  • possible duplicate of [Reference: all basic ways to sort arrays and data in PHP](http://stackoverflow.com/questions/17364127/reference-all-basic-ways-to-sort-arrays-and-data-in-php) – Nikolaj Sarry Sep 10 '15 at 14:43

1 Answers1

2

There are perfectly suitable approaches detailed here, but considering the actual structure of your array, this probably requires a bit more explanation. Specifically, here's how you can sort by both keys and values:

uksort($array, function ($siteA, $siteB) use ($array) {
    $priceA = $array[$siteA]['price'];
    $priceB = $array[$siteB]['price'];

    if ($priceA == $priceB) {
        return strcmp($siteA, $siteB);
    }
    if (!$priceB) {
        return -1;
    }
    if (!$priceA) {
        return 1;
    }
    return $priceB - $priceA;
});

You might need to adjust the specific comparisons and return logic here, but this illustrates the approach.

Community
  • 1
  • 1
deceze
  • 471,072
  • 76
  • 664
  • 811
  • Awesome! Thanks man! I was looking at your answer over here: http://stackoverflow.com/questions/31183575/access-array-key-using-uasort-in-php But couldn't get it work :(. But this one works perfectly, so awesome, thanks! – Erik van de Ven Sep 10 '15 at 14:55
  • One question left. I changed the ```return $priceB - $priceA;``` to ```return $priceA - $priceB;``` so the prices are from high to low. But "no price" should be at the bottom. So first prices from low to high, and then "no prices". Any tips? Tried to change different values, but no luck so far. – Erik van de Ven Sep 10 '15 at 15:14
  • 1
    That's what the `if (!$priceA)` conditions are for. *If prices are equal, sort by site, else if price B is nothing, then A is higher, else if price A is nothing, B is higher, else sort by price.* Adjust those conditions accordingly to what your actual "none" price value is. – deceze Sep 10 '15 at 15:18
  • I needed to add ```if($priceB < $priceA){ return 1; } if($priceB > $priceA){ return -1; }``` to make this work :) Now it works perfectly. For anyone who is looking for the same solution.... – Erik van de Ven Sep 14 '15 at 08:36