Access array key using uasort in PHP
Asked Answered
E

2

12

If have a rather basic uasort function in PHP that looks like this:

uasort($arr, function($a, $b) {
                if ($a > $b)
                    return -1;
                if ($a < $b)
                    return 1;
...
}

The array I'm trying to sort looks like the following:

{[1642] => 1, [9314] => 4, [1634] => 3 ...}

It contains integers that are my main comparison criteria. However, if the integers are equal, then I would like to access their key values, inside the uasort function and do some magic with it to figure out the sorting from there.

I have no clue how to do that as it seems that the $a and $b variables that get passed into the function are just the integers without the corresponding keys but there should be a way to access the key as well since I'm using a function to actually preserve the keys. Any ideas?

Epode answered 2/7, 2015 at 11:37 Comment(2)
What magic are we talking about here? There may be other ways to do this.Artemisa
The 'magic' or the logic of the application is quite messed up as it involves special DB queries if the integers are equal. Luckily, most of the time they are not and I could think of a workaround, for example, by creating another 2D array which hold the integers as one value and the key as another then feed that to the uasort. However, I'm hoping that there's a better and easier way to do that.Epode
H
18
uksort($arr, function ($a, $b) use ($arr) {
    return $arr[$a] - $arr[$b] ?: $a - $b;
});

You can get the values by the keys, so use uksort which gives you the keys. Replace $a - $b with your appropriate magic, here it's just sorting by the key's value.

Haruspex answered 2/7, 2015 at 12:6 Comment(3)
Just out of interest: Is it just my PHP 5.3.1 environment, or do other users observe problems with the use() clause too?Rosemare
It works in my environment too, if you use use(&$arr) rather than just use($arr). The contents (i. e. the order) of $arr changes over time and use($arr) would only be working with a static copy, see here:php.net/manual/de/functions.anonymous.phpRosemare
Thank you, exactly what I needed. I guest 'uasort' is just the wrong function to use in this case. I'm running on PHP 5.4 and 5.5 so no problems with the 'use', works out of the box.Epode
R
0

The use directive (in deceze's solution) does not work in my old PHP 5.3.1 installation, while this will deliver the result:

$arr=array('1642'=>1,'9314'=>2,'1634'=>1,'1633'=>5,'1636'=>7,'1610'=>1);
print_r($arr);

function mycmp($a, $b) {
 if ($a > $b)  return -1;
 if ($a < $b)  return 1;
 else return 0;
}
function mysrt($arr){
 foreach ($arr as $k => $v) $new[$k]="$v $k";
 uasort($new, 'mycmp'); $ret=array();
 foreach ($new as $k => $v) $ret[$k]=$arr[$k];
 return $ret;
}
print_r(mysrt($arr));

mysrt() does not sort 'in-place' but will return the sorted array. And of course: my "magic" on the key sorting is rather basic. Keys will get sorted in the same way as the values. By modifying the statement $new[$k]="$v $k"; you can change the behaviour to suit your needs.

as a side note ...

deceze's solution will work on my server only when I use use(&$arr) instead of use($arr):

uksort($arr, function ($a, $b) use(&$arr) {
    return $arr[$a] - $arr[$b] ? $arr[$a] - $arr[$b] : $a - $b;
});
Rosemare answered 2/7, 2015 at 12:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.