0

I've been breaking my head over the following problem.

I've got this array:

[596] => 2
[9] => 2
[358] => 2
[1579] => 1
[156] => 1
[576] => 1
[535] => 1

As you can see, the values are ordered in a descending way, but the keys are random. I would like to keys to be sorted DESC as well though. I've been playing with array_multisort, but I haven't been able to fix the problem with it. The first problem that I encountered was the fact that array_multisort reindexes numeric keys. I changed to keys to a non-numeric variant, namely k596 etc... That made me able to sort the keys, but not like I wanted it to.

[k9] => 2
[k596] => 2
[k358] => 2
[k576] => 1
[k535] => 1
[k1579] => 1
[k156] => 1

The result that I would like to see in the end is:

[k596] => 2
[k358] => 2
[k9] => 2
[k1579] => 1
[k576] => 1
[k535] => 1
[k156] => 1

Is anyone able to help me out here? There must be a simple way to do this, right?

user1796440
  • 366
  • 3
  • 11

2 Answers2

1

Ok this question is a bit more tricky then I thought! Given an array $arry = array('a'=>'hilbert', 'b'=>'noether', 'c'=>'landau');

I would generate a second array containing tuples like this:

$brry = array();
foreach($arry as $key => $value){
    $brry[] = array($key,$value);
}

//Now $brry looks like:
//$brry:
//    [0] => array('a','hilbert');
//    [1] => array('b','noether');
//    [2] => array('c','landau');

//now you can easily sort it!
usort($brry, "cmp");

//And then transform it back to the array structure you have before
foreach($brry as $value){
    $crry[$value[0]] = $value[1];
}

//with this sorting function cmp:
function cmp($first, $second){
    if(strcmp($first[1], $second[1]) != 0){
        return strcmp($first[1], $second[1]);
    }
    else{
        return strcmp($first[0], $second[0]);
    }
}

The function cmp sorts by strings now so strcmp("192","20") > 0 while this might not be true for integers!

mjb4
  • 989
  • 1
  • 9
  • 14
1
uksort($array, function ($a, $b) use ($array) {
    if ($array[$a] != $array[$b]) {
        return $array[$a] - $array[$b];
    }
    return $a - $b;
});

Insert appropriate comparison operations, using simply - here as an example. This is somewhat trickier if you're dependent on PHP < 5.3 and don't have anonymous functions.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • Strange, I tried similar approach but used `$array` as global and ended up with a warning "Array was modified"; this however seems to work. – Salman A Jan 20 '14 at 17:01
  • instead of return $a - $b; `return $a > $b;` and then `$array =array_reverse($array,TRUE);` – Nouphal.M Jan 20 '14 at 17:34
  • @Nouphal That's wrong. You need to return a value < 0, 0 or > 0, not a Boolean. – deceze Jan 20 '14 at 19:08