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语法(5)
Oct 09 PHP
php 获取本机外网/公网IP的代码
May 09 PHP
PHP设计模式之代理模式的深入解析
Jun 13 PHP
php缩小png图片不损失透明色的解决方法
Dec 25 PHP
php数组中删除元素之重新索引的方法
Sep 16 PHP
php实现RSA加密类实例
Mar 26 PHP
PHP socket 模拟POST 请求实例代码
Jul 18 PHP
Yii2框架dropDownList下拉菜单用法实例分析
Jul 18 PHP
yii2实现 &quot;上一篇,下一篇&quot; 功能的代码实例
Feb 04 PHP
PHP ADODB生成HTML表格函数rs2html功能【附错误处理函数用法】
May 29 PHP
PHP中的访问修饰符简单比较
Feb 02 PHP
laravel多条件查询方法(and,or嵌套查询)
Oct 09 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代码中使用换行及(\n或\r\n和br)的应用
2013/02/02 PHP
php实现文件编码批量转换
2014/03/10 PHP
php匹配字符中链接地址的方法
2014/12/22 PHP
在Laravel中使用DataTables插件的方法
2018/05/29 PHP
jquery $(document).ready() 与window.onload的区别
2009/12/28 Javascript
新浪微博字数统计 textarea字数统计实现代码
2011/08/28 Javascript
Dom操作之兼容技巧分享
2011/09/20 Javascript
用js实现小球的自由移动代码
2013/04/22 Javascript
jquery入门必备的基本认识及实例(整理)
2013/06/24 Javascript
js重写alert控件(适合学习js的新手朋友)
2014/08/24 Javascript
JS+DIV实现鼠标划过切换层效果的方法
2015/05/25 Javascript
JavaScript截断字符串的方法
2015/07/15 Javascript
jquery实现适用于门户站的导航下拉菜单效果代码
2015/08/24 Javascript
AngularJS入门教程引导程序
2016/08/18 Javascript
JS验证图片格式和大小并预览的简单实例
2016/10/11 Javascript
巧用Vue.js+Vuex制作专门收藏微信公众号的app
2016/11/03 Javascript
jquery实现文本框的禁用和启用
2016/12/07 Javascript
Three.js基础部分学习
2017/01/08 Javascript
JQuery实现定时刷新功能代码
2017/05/09 jQuery
angular学习之从零搭建一个angular4.0项目
2017/07/10 Javascript
Vue中&quot;This dependency was not found&quot;问题的解决方法
2018/06/19 Javascript
从零开始封装自己的自定义Vue组件
2018/10/09 Javascript
JavaScript中clientWidth,offsetWidth,scrollWidth的区别
2021/01/25 Javascript
详解Python文本操作相关模块
2017/06/22 Python
Pandas探索之高性能函数eval和query解析
2017/10/28 Python
python中for循环输出列表索引与对应的值方法
2018/11/07 Python
Python正则表达式和re库知识点总结
2019/02/11 Python
使用python实现滑动验证码功能
2019/08/05 Python
迪梵英国官方网站:Darphin英国
2017/12/06 全球购物
Parfumdreams芬兰:购买香水和化妆品
2021/02/13 全球购物
爱护公物演讲稿
2014/09/09 职场文书
2014年小学教学工作总结
2014/11/13 职场文书
党支部先进事迹材料
2014/12/24 职场文书
计算机实训心得体会
2016/01/14 职场文书
Python Django模型详解
2021/10/05 Python
mysql中varchar类型的日期进行比较、排序等操作的实现
2021/11/17 MySQL