3

I'm trying to sort an array of values.

The possible values in the array are 'neg_infinity',... {real numbers},.., 'infinity'

<?php
$a = array(
  array('column' => 3),
  array('column' => -1),
  array('column' => 1),
  array('column' => .1),
  array('column' => 2),
  array('column' => 'infinity'),
  array('column' => 'neg_infinity'),
  array('column' => 'infinity'),
);

I want:

    $a = array(
      array('column' => 'neg_infinity'),
      array('column' => -1),
      array('column' => .1),
      array('column' => 1),
      array('column' => 2),
      array('column' => 3),
      array('column' => 'infinity'),
      array('column' => 'infinity'),
    );

I've been playing around with uasort.

Anybody have a solution to his problem?


TEST DRIVER

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

$a = array('a' => 'infinity', 'b' => 8, 'c' => -1,'e' => 2, 'f' => 5, 'g' => 3, 'h' => -4, 'd' => 'neg_infinity');


uasort($a, 'cmp');


var_dump($a);
1
  • 4
    What did you try? Post your example and we can probably tell you why you failed. Commented Aug 31, 2011 at 20:08

3 Answers 3

5

Use this for your sorting function:

function cmp($a, $b) {
    if ($a == 'neg_infinity') {
       return -1
    }
    if ($a == 'infinity') {
       return 1
    }
    return ($a < $b ? -1 : 1)
}
Sign up to request clarification or add additional context in comments.

5 Comments

What if both $a and $b == 'infinity'?
Then the a value will take priority. If you want that to be different (or randomized), you'll have to add an extra clause to handle the case. It's the same if a == b, the a value will take priority.
I actually came up with this solution as well. But it doesn't work.
Hm.. didn't notice you've actually got a multidimensional array. You'd want to use if ($a['column'] == 'neg_infinity') and the like instead. Otherwise you're directly comparing arrays to strings/integers, which'll fail.
@Marc B: you need to check $b too, otherwise you're gonna miss the comparison when 'infinity' is $b
5

Something like this should work:

function cmp($a, $b) {
    if ($a == $b) {
        return 0;
    }
    if ($a == 'neg_infinity') {
        return -1;
    }
    if ($a == 'infinity') {
        return 1;
    }
    return ($a < $b) ? -1 : 1;
}

2 Comments

Do you really need the first conditional?
@animuson: Maybe not, but per the docs, "The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second."
1

You tricky bastard! I'll give you plus one because it took me 20 minutes to get it was an array of arrays.

function cmp($a, $b) {
    if ($a['column'] == 'neg_infinity') {
        return -1;
    }
    if ($a['column'] == 'infinity') {
        return 1;
    }

    if ($b['column'] == 'neg_infinity') {
        return 1;
    }
    if ($b['column'] == 'infinity') {
        return -1;
    }
    if ($a['column'] == $b['column']) {
        return 0;
    }
    return ($a['column'] < $b['column']) ? -1 : 1;
} 

it is tested: http://codepad.org/13GuICbH

IdeOne is too mainstream, ya know.

2 Comments

Thanks. I forgot to check the $b values.
It slipped from me too at the beginning but at a certain point you're going to compare -1 and neg_infinity for sure and if you don't check $b you miss that comparison.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.