0

I have two key-value arrays. The keys in both arrays are the same, but in the first array they point to a string label and in the second they point to an integer number:

$labelArray (size=n)
 ID_1 => LABEL_1 
 ID_2 => LABEL_2
 ...up to n items

$countArray (size=n)
 ID_1 => Count_1
 ID_2 => Count_1
 ...up to n items

I like to order the labelArray by the values of the countArray. So far I only came up with a very convoluted solution, where I seperatly order the keys and then create a new array like so:

// my current (very convoluted solution) 
$keys = array_keys($labelArray);
$orderByCount = function($a, $b)  use ($countArray ) {
 return $countArray [$b] - $countArray [$a];
}; 
usort($keys, $orderByCount);
$labelArrayNewOrder = array();
foreach ($keys as $key) {  
 $labelArrayNewOrder[$key] = $labelArray[$key];
}

Is there any solution where I don't have to create a new array, but just reorder the existing labelArray?

This should be a common problem, but I could not find a solution online. Only pointers to ordering of multidimensional arrays (How do I Sort a Multidimensional Array in PHP) but I think my problem is different.

Community
  • 1
  • 1
Pascal Klein
  • 23,665
  • 24
  • 82
  • 119

1 Answers1

1

Sure. Since you want to order by something that is a custom function of the array keys, the appropriate tool would be uksort. You can use it directly with your $orderByCount comparer:

$orderByCount = function($a, $b)  use ($countArray ) {
     return $countArray [$b] - $countArray [$a];
};

uksort($labelArray, $orderByCount);

Two points of note that are however not directly related to your question:

  1. Be very careful if you are using the return $x - $y shortcut from the comparison function! The result is cast into an integer before it's interpreted, which means that if the values involved are floats you will perhaps get wrong results for the sort. In this case "counts" implies that the values are indeed integer and will present no issue, but it's something to keep in mind.
  2. Your comparison function gives a descending sort, which is not immediately obvious. It would be good to help the future reader of the code, perhaps by naming the comparer $orderByCountDesc.
Jon
  • 428,835
  • 81
  • 738
  • 806