views:

121

answers:

4

This is my array:

$arr = array(-3, -4, 1, -1, 2, 4, -2, 3);

I want to sort it like this:

1
2
3
4
-1
-2
-3
-4

So first there would be values greated than zero sorted from the lowest value to the highest value, then there would be negative values sorted from the highest value to the lowest value.

Is there some elegant way to do this?

+2  A: 

usort() can sort anything with your own set of rules
dunno if it fits to your aesthetics feelings

Col. Shrapnel
+5  A: 

Here's a non-usort() method, assuming zero is irrelevant...

<?php

$arr = array(-3, -4, 1, -1, 2, 4, -2, 3);

$positive = array_filter($arr, function($x) { return $x > 0; });
$negative = array_filter($arr, function($x) { return $x < 0; });

sort($positive);
rsort($negative);

$sorted = array_merge($positive, $negative);
print_r($sorted);

?>

EDIT: no PHP 5.3? Use create_function() as you say:

$positive = array_filter($arr, create_function('$x', 'return $x > 0;'));
$negative = array_filter($arr, create_function('$x', 'return $x < 0;'));
BoltClock
I would change the last bit to:$sorted = array_merge($positive,$negative);
Prot0
@Prot0: I just did.
BoltClock
I have PHP < 5.3 (PHP 5.2.8 or something like that) so I tried this and it doesn't work. The solution is to use create_function() :) That works in older PHP 5 versions.
Richard Knop
@Richard Knop: I know you're not lazy, but I updated my answer with the PHP < 5.3 solution anyway for the benefit of others.
BoltClock
I believe salathe's solution is better. :)
Savageman
@Savageman: me too. One of the upvotes on his answer is mine.
BoltClock
+1  A: 

I'm sure this can be made shorter but this works:

<?php
function cmp($a, $b) 
{
        if ($a == $b) 
                return 0;
        if($a>=0 && $b>=0 )
                return ($a < $b) ? -1 : 1;
        if( $a<=0 && $b<=0)
                return (-$a < -$b) ? -1 : 1;
        if($a>0)
                return -1; 
        return 1;
}

$a = array(-3, -4, 1, -1, 2, 4, -2, 3);                                                                                                                                                                        

var_dump($a);
usort($a, "cmp");
var_dump($a);

?>

Working link.

codaddict
+9  A: 

Here's a simple comparison function:

function sorter($a, $b) {
    if ($a > 0 && $b > 0) {
        return $a - $b;
    } else {
        return $b - $a;
    }
}

$arr = array(-3, -4, 1, -1, 2, 4, -2, 3);
usort($arr, 'sorter');
var_dump($arr);

Aside: With the above, zero falls on the negative side of the fence. Change the > to >= if you want them to rise to the top of the positive side of said fence.

salathe