In PHP the solution to the problem of usort changing the original position at the same value

  • 2020-05-10 17:48:51
  • OfStack

After PHP 4.1.0, the original location of usort may change when the values are the same, as stated in the document:
If two members compare as equal, their order in the sorted array is undefined.
That is, if the two values of the comparison are the same, their order in the sorted result is random. If you need to keep the original location of the same value, you can refer to the method in this article.
Demo data:
 
<?php 
/* 
 To solve  PHP  In the  usort  The problem of changing the original position at the same value  
 The author: Artlover http://www.CodeBit.cn 
*/ 
$arr = array( 
array('a' => 5, 'b' => 3), 
array('a' => 5, 'b' => 1), 
array('a' => 5, 'b' => 4), 
array('a' => 5, 'b' => 2), 
); 
?> 

The value of the first element in the array is the same, and the desired result is to keep the existing position the same, that is, the order of b is 3,1,4,2
With usort sorting, the original order may change when comparing fields with the same value
 
<?php 
/* 
 To solve  PHP  In the  usort  The problem of changing the original position at the same value  
 The author: Artlover http://www.CodeBit.cn 
*/ 
$callback = create_function('$a,$b', 'return ($a["a"] == $b["a"])?0:(($a["a"] > $b["a"]) ? 1 : -1);'); 
usort($arr, $callback); 
?> 

Results:
 
Array 
( 
[0] => Array 
( 
[a] => 5 
[b] => 2 
) 
[1] => Array 
( 
[a] => 5 
[b] => 4 
) 
[2] => Array 
( 
[a] => 5 
[b] => 1 
) 
[3] => Array 
( 
[a] => 5 
[b] => 3 
) 
) 

Although the sorted fields have the same value, usort shuffles the whole array.
If you want to keep the original position while comparing the same values, you can use array_multisort:
 
<?php 
/* 
 To solve  PHP  In the  usort  The problem of changing the original position at the same value  
 The author: Artlover http://www.CodeBit.cn 
*/ 
//  Index counter  
$i = 0; 
//  create 2 Two empty arrays, one 1 Save the fields to be sorted, no 2 Save the original index information  
$a = $index = array(); 
foreach ($arr as $key => $data) { 
$a[$key] = $data['a']; 
$index[] = $i++; 
} 
//  The first 1 Arrays are sorted first, then by the original index  
array_multisort($a, SORT_ASC, $index, SORT_ASC, $arr); 
?> 

Results:
 
Array 
( 
[0] => Array 
( 
[a] => 5 
[b] => 3 
) 
[1] => Array 
( 
[a] => 5 
[b] => 1 
) 
[2] => Array 
( 
[a] => 5 
[b] => 4 
) 
[3] => Array 
( 
[a] => 5 
[b] => 2 
) 
) 

Related articles: