PHP中usort在值相同时改变原始位置问题的解决方法


Posted in PHP onNovember 27, 2011

从 PHP 4.1.0 后,usort 在比较的值相同时,原始位置可能会改变,文档中是这样说的:
If two members compare as equal, their order in the sorted array is undefined.
也就是说,如果比较的2个值相同,则它们在排序结果中的顺序是随机的。如果你需要保持相同值的原始位置,可以参考本文的方法。
演示数据:

<?php 
/* 
解决 PHP 中 usort 在值相同时改变原始位置的问题 
作者: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), 
); 
?>

数组中第一个元素的值是相同的,期望的结果是保持现有的位置不变,即 b 的顺序为 3,1,4,2
用 usort 排序,当比较字段的值相同时,原始顺序可能会改变
<?php 
/* 
解决 PHP 中 usort 在值相同时改变原始位置的问题 
作者: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); 
?>

结果:
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 
) 
)

虽然排序字段的值相同,但是 usort 却将整个数组的顺序打乱了。
如果要在比较的值相同时保持原始位置,可以用 array_multisort :
<?php 
/* 
解决 PHP 中 usort 在值相同时改变原始位置的问题 
作者:Artlover http://www.CodeBit.cn 
*/ 
// 索引计数器 
$i = 0; 
// 创建2个空数组,第一个保存要排序的字段,第二个保存原始索引信息 
$a = $index = array(); 
foreach ($arr as $key => $data) { 
$a[$key] = $data['a']; 
$index[] = $i++; 
} 
// 第一个数组先排,接着按原始索引排 
array_multisort($a, SORT_ASC, $index, SORT_ASC, $arr); 
?>

结果:
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 
) 
)
PHP 相关文章推荐
通过ODBC连接的SQL SERVER实例
Oct 09 PHP
PHP个人网站架设连环讲(四)
Oct 09 PHP
PHP高级OOP技术演示
Aug 27 PHP
MYSQL 小技巧 -- LAST_INSERT_ID
Nov 24 PHP
PHP中浮点数计算比较及取整不准确的解决方法
Jan 09 PHP
php文件上传类完整实例
May 14 PHP
PHP随机获取未被微信屏蔽的域名(微信域名检测)
Mar 19 PHP
[原创]php实现数组按拼音顺序排序的方法
May 03 PHP
详解PHP序列化和反序列化原理
Jan 15 PHP
PHP常见过waf webshell以及最简单的检测方法
May 21 PHP
laravel Model 执行事务的实现
Oct 10 PHP
phpinfo的知识点总结
Oct 10 PHP
PHP中strtotime函数使用方法详解
Nov 27 #PHP
遍历指定目录下的所有目录和文件的php代码
Nov 27 #PHP
用PHP写的基于Memcache的Queue实现代码
Nov 27 #PHP
PHP中去除换行解决办法小结(PHP_EOL)
Nov 27 #PHP
php操作SVN版本服务器类代码
Nov 27 #PHP
支持中文的php加密解密类代码
Nov 27 #PHP
php UBB 解析实现代码
Nov 27 #PHP
You might like
php+mysql结合Ajax实现点赞功能完整实例
2015/01/30 PHP
初识laravel5
2015/03/02 PHP
php pdo oracle中文乱码的快速解决方法
2016/05/16 PHP
jQuery动态添加、删除元素的方法
2014/01/09 Javascript
如何判断微信内置浏览器(通过User Agent实现)
2014/09/01 Javascript
jquery动态导航插件dynamicNav用法实例分析
2015/09/06 Javascript
AngularJS ng-app 指令实例详解
2016/07/30 Javascript
基于js中的原型、继承的一些想法
2016/08/10 Javascript
JS中with的替代方法与String中的正则方法详解
2016/12/23 Javascript
Angular的$http与$location
2016/12/26 Javascript
js实现自定义路由
2017/02/04 Javascript
JavaScript 函数的定义-调用、注意事项
2017/04/16 Javascript
bootstrap-table formatter 使用vue组件的方法
2019/05/09 Javascript
js+html实现点名系统功能
2019/11/05 Javascript
js实现拾色器插件(ColorPicker)
2020/05/21 Javascript
对vue生命周期的深入理解
2020/12/03 Vue.js
[48:48]2014 DOTA2国际邀请赛中国区预选赛 SPD-GAMING VS Dream TIME
2014/05/21 DOTA
wxPython事件驱动实例详解
2014/09/28 Python
Python实现从百度API获取天气的方法
2015/03/11 Python
Python selenium 父子、兄弟、相邻节点定位方式详解
2016/09/15 Python
Python切换pip安装源的方法详解
2016/11/18 Python
TensorFlow实现卷积神经网络CNN
2018/03/09 Python
Python简单实现阿拉伯数字和罗马数字的互相转换功能示例
2018/04/17 Python
python微元法计算函数曲线长度的方法
2018/11/08 Python
python实现微信防撤回神器
2019/04/29 Python
Flask框架学习笔记之模板操作实例详解
2019/08/15 Python
python+django+rest框架配置创建方法
2019/08/31 Python
Python txt文件常用读写操作代码实例
2020/08/03 Python
python读取excel数据绘制简单曲线图的完整步骤记录
2020/10/30 Python
在线吉他课程,学习如何弹吉他:Fender Play
2019/02/28 全球购物
初中生学习的自我评价
2013/11/14 职场文书
基层党员公开承诺书
2014/05/29 职场文书
违反单位工作制度检讨书
2014/10/25 职场文书
生活委员竞选稿
2015/11/21 职场文书
Pygame Event事件模块的详细示例
2021/11/17 Python
TV动画《八十龟酱观察日记》第四季宣传PV公布
2022/04/06 日漫