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 Zip解压 文件在线解压缩的函数代码
May 26 PHP
PHP学习之整理字符串
Apr 17 PHP
解析smarty 截取字符串函数 truncate的用法介绍
Jun 20 PHP
PHP中使用asort进行中文排序失效的问题处理
Aug 18 PHP
destoon切换城市后实现logo旁边显示地区名称的方法
Aug 21 PHP
CI框架学习笔记(二) -入口文件index.php
Oct 27 PHP
CentOS下PHP安装Oracle扩展
Feb 15 PHP
基于CakePHP实现的简单博客系统实例
Jun 28 PHP
PHP编程入门的基本语法知识点总结
Jan 26 PHP
[原创]php常用字符串输出方法分析(echo,print,printf及sprintf)
Jul 09 PHP
PHP chr()函数讲解
Feb 11 PHP
PHP扩展Swoole实现实时异步任务队列示例
Apr 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 命令行参数详解及应用
2011/05/18 PHP
thinkphp普通查询与表达式查询实例分析
2014/11/24 PHP
基于PHP-FPM进程池探秘
2017/10/17 PHP
浅谈thinkphp的nginx配置,以及重写隐藏index.php入口文件方法
2019/10/12 PHP
基于PHP的微信公众号的开发流程详解
2020/08/07 PHP
为数据添加append,remove功能
2006/10/03 Javascript
Node.js生成HttpStatusCode辅助类发布到npm
2013/04/09 Javascript
javascript检测对象中是否存在某个属性判断方法小结
2013/05/19 Javascript
正则表达式优化JSON字符串的技巧
2015/12/24 Javascript
javascript截图 jQuery插件imgAreaSelect使用详解
2016/05/04 Javascript
Bootstrap table两种分页示例
2016/12/23 Javascript
jquery实现下拉框多选方法介绍
2017/01/03 Javascript
总结4个方面优化Vue项目
2019/02/11 Javascript
详解JS判断页面是在手机端还是在PC端打开的方法
2019/04/26 Javascript
layui添加动态菜单与选项卡 AJAX请求的例子
2019/09/25 Javascript
jQuery 选择器用法基础入门示例
2020/01/04 jQuery
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
2020/04/07 Javascript
vue+iview框架实现左侧动态菜单功能的示例代码
2020/07/23 Javascript
基于JavaScript实现简单抽奖功能代码实例
2020/10/20 Javascript
使用url_helper简化Python中Django框架的url配置教程
2015/05/30 Python
python ansible服务及剧本编写
2017/12/29 Python
Python装饰器用法实例总结
2018/02/07 Python
Django中日期处理注意事项与自定义时间格式转换详解
2018/08/06 Python
基于Django框架利用Ajax实现点赞功能实例代码
2018/08/19 Python
对python3.4 字符串转16进制的实例详解
2019/06/12 Python
Anaconda+Pycharm环境下的PyTorch配置方法
2020/03/13 Python
Python如何合并多个字典或映射
2020/07/24 Python
利用HTML5 Canvas API绘制矩形的超级攻略
2016/03/21 HTML / CSS
使用html2canvas实现将html内容写入到canvas中生成图片
2020/01/03 HTML / CSS
美国一家著名的儿童鞋制造商:Stride Rite
2017/01/02 全球购物
HTC VIVE美国官网:VR虚拟现实眼镜
2018/02/13 全球购物
法律专业推荐信范文
2013/11/29 职场文书
2014年关于两会精神的心得体会
2014/03/17 职场文书
亮剑观后感
2015/06/05 职场文书
深度学习tensorflow基础mnist
2021/04/14 Python
MySql数据库 查询时间序列间隔
2022/05/11 MySQL