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 相关文章推荐
支持oicq头像的留言簿(一)
Oct 09 PHP
一个MYSQL操作类
Nov 16 PHP
PHP手机号码归属地查询代码(API接口/mysql)
Sep 04 PHP
做了CDN获取用户真实IP的函数代码(PHP与Asp设置方式)
Apr 13 PHP
php数组声明、遍历、数组全局变量使用小结
Jun 05 PHP
php通过ksort()函数给关联数组按照键排序的方法
Mar 18 PHP
PHP+MYSQL实现用户的增删改查
Mar 24 PHP
php简单实现sql防注入的方法
Apr 22 PHP
PHP MVC框架skymvc支持多文件上传
May 26 PHP
详解php curl带有csrf-token验证模拟提交方法
Apr 18 PHP
PHP如何实现阿里云短信sdk灵活应用在项目中的方法
Jun 14 PHP
laravel框架数据库配置及操作数据库示例
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
PHP5中MVC结构学习
2006/10/09 PHP
php 全文搜索和替换的实现代码
2008/07/29 PHP
PHP5.5安装PHPRedis扩展及连接测试方法
2017/01/22 PHP
类似框架的js代码
2006/11/09 Javascript
ExtJS 下拉多选框lovcombo
2010/05/19 Javascript
js实现的捐赠管理完整实例
2015/01/20 Javascript
Javascript中的方法链(Method Chaining)介绍
2015/03/15 Javascript
js性能优化技巧
2015/11/29 Javascript
jquery常用的12个小功能
2016/07/22 Javascript
javascript 缓冲运动框架的实现
2017/09/29 Javascript
Vue2.5通过json文件读取数据的方法
2018/02/27 Javascript
vue中keep-alive的用法及问题描述
2018/05/15 Javascript
js实现左右两侧浮动广告
2018/07/09 Javascript
JS获取当前时间的年月日时分秒及时间的格式化的方法
2019/12/18 Javascript
js this 绑定机制深入详解
2020/04/30 Javascript
django简单的前后端分离的数据传输实例 axios
2020/05/18 Javascript
vue实现桌面向网页拖动文件的示例代码(可显示图片/音频/视频)
2021/03/01 Vue.js
详解Python的Django框架中的模版相关知识
2015/07/15 Python
Python3使用requests登录人人影视网站的方法
2016/05/11 Python
python字典多键值及重复键值的使用方法(详解)
2016/10/31 Python
Python 中开发pattern的string模板(template) 实例详解
2017/04/01 Python
django之session与分页(实例讲解)
2017/11/13 Python
Windows下的Jupyter Notebook 安装与自定义启动(图文详解)
2018/02/21 Python
python实现微信远程控制电脑
2018/02/22 Python
对python mayavi三维绘图的实现详解
2019/01/08 Python
pycharm内无法import已安装的模块问题解决
2020/02/12 Python
开发中都用到了那些设计模式?用在什么场合?
2014/08/21 面试题
室内设计专业个人的自我评价
2013/12/18 职场文书
市场营销求职信范文
2014/02/21 职场文书
企业安全生产演讲稿
2014/05/09 职场文书
中国梦演讲稿开场白
2014/08/28 职场文书
献爱心大型公益活动策划方案
2014/09/15 职场文书
2015年建党94周年演讲稿
2015/03/19 职场文书
周一给客户的问候语
2015/11/10 职场文书
gateway与spring-boot-starter-web冲突问题的解决
2021/07/16 Java/Android
python基础之函数的定义和调用
2021/10/24 Python