@@ -328,41 +328,24 @@ function cm_tools_array_remove_values(&$haystack, $values) {
328328 * @param callable $cmp_function
329329 */
330330function cm_tools_stable_usort(&$array, $cmp_function) {
331- // Arrays of size < 2 require no action.
332- if (count($array) < 2) return;
333- // Split the array in half
334- $halfway = count($array) / 2;
335- $array1 = array_slice($array, 0, $halfway);
336- $array2 = array_slice($array, $halfway);
337- // Recurse to sort the two halves
338- cm_tools_stable_usort($array1, $cmp_function);
339- cm_tools_stable_usort($array2, $cmp_function);
340- // If all of $array1 is <= all of $array2, just append them.
341- if (call_user_func($cmp_function, end($array1), $array2[0]) < 1) {
342- $array = array_merge($array1, $array2);
343- return;
344- }
345- // Merge the two sorted arrays into a single sorted array
346- $array = array();
347- $ptr1 = $ptr2 = 0;
348- while ($ptr1 < count($array1) && $ptr2 < count($array2)) {
349- if (call_user_func($cmp_function, $array1[$ptr1], $array2[$ptr2]) < 1) {
350- $array[] = $array1[$ptr1++];
351- }
352- else {
353- $array[] = $array2[$ptr2++];
354- }
355- }
356- // Merge the remainder
357- while ($ptr1 < count($array1)) $array[] = $array1[$ptr1++];
358- while ($ptr2 < count($array2)) $array[] = $array2[$ptr2++];
359- return;
331+ $index = 0;
332+ foreach ($array as &$item) {
333+ $item = array($index++, $item);
334+ }
335+ $result = usort($array, function($a, $b) use ($cmp_function) {
336+ $result = call_user_func($cmp_function, $a[1], $b[1]);
337+ return $result == 0 ? $a[0] - $b[0] : $result;
338+ });
339+ foreach ($array as &$item) {
340+ $item = $item[1];
341+ }
342+ return $result;
360343}
361344
362345/**
363346 * Sort an array by user-defined comparison function, preserving indexes.
364347 *
365- * However, unlike ussort , equal values maintain their order.
348+ * However, unlike uasort , equal values maintain their order.
366349 *
367350 * The comparison function must return an integer less than, equal to, or
368351 * greater than zero if the first argument is considered to be
@@ -372,40 +355,18 @@ function cm_tools_stable_usort(&$array, $cmp_function) {
372355 * @param callable $cmp_function
373356 */
374357function cm_tools_stable_uasort(&$array, $cmp_function) {
375- if(count($array) < 2) {
376- return;
377- }
378- $halfway = count($array) / 2;
379- $array1 = array_slice($array, 0, $halfway, TRUE);
380- $array2 = array_slice($array, $halfway, NULL, TRUE);
381-
382- cm_tools_stable_uasort($array1, $cmp_function);
383- cm_tools_stable_uasort($array2, $cmp_function);
384- if(call_user_func($cmp_function, end($array1), reset($array2)) < 1) {
385- $array = $array1 + $array2;
386- return;
387- }
388- $array = array();
389- reset($array1);
390- reset($array2);
391- while(current($array1) && current($array2)) {
392- if(call_user_func($cmp_function, current($array1), current($array2)) < 1) {
393- $array[key($array1)] = current($array1);
394- next($array1);
395- } else {
396- $array[key($array2)] = current($array2);
397- next($array2);
398- }
399- }
400- while(current($array1)) {
401- $array[key($array1)] = current($array1);
402- next($array1);
403- }
404- while(current($array2)) {
405- $array[key($array2)] = current($array2);
406- next($array2);
407- }
408- return;
358+ $index = 0;
359+ foreach ($array as &$item) {
360+ $item = array($index++, $item);
361+ }
362+ $result = uasort($array, function($a, $b) use ($cmp_function) {
363+ $result = call_user_func($cmp_function, $a[1], $b[1]);
364+ return $result == 0 ? $a[0] - $b[0] : $result;
365+ });
366+ foreach ($array as &$item) {
367+ $item = $item[1];
368+ }
369+ return $result;
409370}
410371
411372/**
0 commit comments