PHP Sort Associative Array first by relativity of value then by other value desc I am trying to sort an associative array by following this scheme:

Sort by 'qt': positives first, non-positives after.  Magnitude does not matter, only sign.
In positive part: sort by sa DESC
In negative part: sort by sa DESC

I managed to have the desired result but by tinkering :
$array = [
    [
        &quot;id&quot; =&gt; 1,
        &quot;qt&quot; =&gt; 1000,
        &quot;sa&quot; =&gt; 50
    ],
    [
        &quot;id&quot; =&gt; 2,
        &quot;qt&quot; =&gt; 0,
        &quot;sa&quot; =&gt; 50
    ],
    [
        &quot;id&quot; =&gt; 3,
        &quot;qt&quot; =&gt; 0,
        &quot;sa&quot; =&gt; 350
    ],
    [
        &quot;id&quot; =&gt; 4,
        &quot;qt&quot; =&gt; 5000,
        &quot;sa&quot; =&gt; 250
    ],
    [
        &quot;id&quot; =&gt; 5,
        &quot;qt&quot; =&gt; 10,
        &quot;sa&quot; =&gt; 9000
    ]
];

$p_qty = array();
$n_qty = array();
foreach ($array as $e) {
    if($e['qt'] &lt;= 0){ array_push($n_qty, $e); }
    else             { array_push($p_qty, $e); }
}
usort($p_qty, function($a, $b){
    return 
        $a['sa'] == $b['sa'] ? (
            $a['sa'] == $b['sa'] ? 0 : (
                $a['qt'] &lt; $b['qt'] ? 1 : -1
            )
        ) : (
            $a['sa'] &lt; $b['sa'] ? 1 : -1
        );
});
usort($n_qty, function($a, $b){
    return 
        $a['sa'] == $b['sa'] ? (
            $a['sa'] == $b['sa'] ? 0 : (
                $a['qt'] &lt; $b['qt'] ? 1 : -1
            )
        ) : (
            $a['sa'] &lt; $b['sa'] ? 1 : -1
        );
});

I get the wanted result: ID [5, 4, 1, 3, 2]
Is there a simple to do the wanted result in a unique usort function ?
You are not actually sorting on qt, only using it to separate two sets (positive qt coming first). Only within each set you are actually sorting (on sa). Therefore, the usort() comparator function could look like this:
usort($array, function($a, $b) {
    // split in positive and negative set
   if ($a['qt'] &lt;= 0 &amp;&amp; $b['qt'] &gt; 0) return 1; // b before a
   if ($a['qt'] &gt; 0 &amp;&amp; $b['qt'] &lt;= 0) return -1; // a before b

   // both a and b are in the same set. sort on `sa` descending
   return $b['sa'] - $a['sa'];
});