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 相关文章推荐
php在线打包程序源码
Jul 27 PHP
PHP采集相关教程之一 CURL函数库
Feb 15 PHP
php地址引用(php地址引用的效率问题)
Mar 23 PHP
解析wamp5下虚拟机配置文档
Jun 27 PHP
PHP获取MySql新增记录ID值的3种方法
Jun 24 PHP
php 批量查询搜狗sogou代码分享
May 17 PHP
9个比较实用的php代码片段
Mar 15 PHP
Laravel 集成 Geetest验证码的方法
May 14 PHP
Laravel利用gulp如何构建前端资源详解
Jun 03 PHP
Laravel使用RabbitMQ的方法示例
Jun 18 PHP
laravel框架模板之公共模板、继承、包含实现方法分析
Aug 30 PHP
PHP dirname简单使用代码实例
Nov 13 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&amp;mysql(六)
2006/10/09 PHP
php checkbox复选框值的获取与checkbox默认值输出方法
2010/05/15 PHP
PHP版本如何选择?应该使用哪个版本?
2015/05/13 PHP
PHP命名空间namespace用法实例分析
2016/09/27 PHP
Thinkphp5.0 框架Model模型简单用法分析
2019/10/11 PHP
juqery 学习之三 选择器 可见性 元素属性
2010/11/25 Javascript
禁止拷贝网页内容的js代码
2014/01/22 Javascript
手机号码,密码正则验证
2014/09/04 Javascript
js验证身份证号有效性并提示对应信息
2015/10/19 Javascript
JS实现仿Windows经典风格的选项卡Tab切换代码
2015/10/20 Javascript
javascript冒泡排序小结
2016/04/10 Javascript
JS之获取样式的简单实现方法(推荐)
2016/09/13 Javascript
Vue.js开发环境快速搭建教程
2017/03/17 Javascript
JS实现两周内自动登录功能
2017/03/23 Javascript
angular4实现tab栏切换的方法示例
2017/10/21 Javascript
javascript实现最长公共子序列实例代码
2018/02/05 Javascript
vue bus全局事件中心简单Demo详解
2018/02/26 Javascript
Angular实现模版驱动表单的自定义校验功能(密码确认为例)
2018/05/17 Javascript
vue自定v-model实现表单数据双向绑定问题
2018/09/03 Javascript
php结合js实现多条件组合查询
2019/05/28 Javascript
layui 富文本赋值,取值,取纯文本值的实例
2019/09/18 Javascript
JavaScript实现随机点名器
2020/03/25 Javascript
解决vue与node模版引擎的渲染标记{{}}(双花括号)冲突问题
2020/09/11 Javascript
Python实现的FTP通信客户端与服务器端功能示例
2018/03/28 Python
使用tensorflow实现矩阵分解方式
2020/02/07 Python
Python flask路由间传递变量实例详解
2020/06/03 Python
.img/.hdr格式转.nii格式的操作
2020/07/01 Python
WEB控件可以激发服务端事件,请谈谈服务端事件是怎么发生并解释其原理?自动传回是什么?为什么要使用自动传回?
2012/02/21 面试题
.NET初级开发工程师面试题(包括Javascript)
2012/08/22 面试题
个人求职信范例
2014/01/29 职场文书
采购部长岗位职责
2014/06/13 职场文书
党支部群众路线整改措施思想汇报
2014/10/10 职场文书
2015年大学迎新晚会总结
2015/07/16 职场文书
优秀团员主要事迹材料
2015/11/05 职场文书
Python集合的基础操作
2021/11/01 Python
python opencv将多个图放在一个窗口的实例详解
2022/02/28 Python