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随机输出名人名言的代码
Oct 07 PHP
CodeIgniter采用config控制的多语言实现根据浏览器语言自动转换功能
Jul 18 PHP
thinkphp实现上一篇与下一篇的方法
Dec 08 PHP
php计算两个整数的最大公约数常用算法小结
Mar 05 PHP
php显示指定目录下子目录的方法
Mar 20 PHP
PHP实现对xml进行简单的增删改查(CRUD)操作示例
May 19 PHP
PHP实现双链表删除与插入节点的方法示例
Nov 11 PHP
PHP fprintf()函数用法讲解
Feb 16 PHP
php微信分享到朋友圈、QQ、朋友、微博
Feb 18 PHP
Yii2框架配置文件(Application属性)与调试技巧实例分析
May 27 PHP
PHP实现常用排序算法的方法
Feb 05 PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
Feb 15 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 array操作10个小技巧分享
2011/06/23 PHP
PHP对象相关知识总结
2017/04/09 PHP
动态创建的表格单元格中的事件实现代码
2008/12/30 Javascript
javascript 打印页面代码
2009/03/24 Javascript
xml 封装与解析(javascript和C#中)
2009/07/26 Javascript
JS短路原理的应用示例 精简代码的途径
2013/12/13 Javascript
jQuery实现鼠标经过图片预览大图效果
2014/04/10 Javascript
jQuery实现的文字hover颜色渐变效果实例
2016/02/20 Javascript
仿百度换肤功能的简单实例代码
2016/07/11 Javascript
webpack实现热更新(实施同步刷新)
2017/07/28 Javascript
Bootstrap 模态框多次显示后台提交多次BUG的解决方法
2017/12/26 Javascript
vue-cli扩展多模块打包的示例代码
2018/04/09 Javascript
vue项目从node8.x升级到12.x后的问题解决
2019/10/25 Javascript
微信小程序实现上拉加载功能
2019/11/20 Javascript
vue使用map代替Aarry数组循环遍历的方法
2020/04/30 Javascript
解决vuecli3中img src 的引入问题
2020/08/04 Javascript
浅谈javascript事件环微任务和宏任务队列原理
2020/09/12 Javascript
Python对小数进行除法运算的正确方法示例
2014/08/25 Python
python常见数制转换实例分析
2015/05/09 Python
Python类的继承和多态代码详解
2017/12/27 Python
python验证码识别教程之灰度处理、二值化、降噪与tesserocr识别
2018/06/04 Python
numpy数组广播的机制
2019/07/12 Python
Python实现元素等待代码实例
2019/11/11 Python
python GUI库图形界面开发之PyQt5计数器控件QSpinBox详细使用方法与实例
2020/02/28 Python
Python多进程编程常用方法解析
2020/03/26 Python
使用css3实现的tab选项卡代码分享
2014/12/09 HTML / CSS
澳大利亚首屈一指的在线购物目的地:Kogan.com
2017/02/02 全球购物
通息工程毕业生自荐信
2013/10/16 职场文书
通用求职信范文模板分享
2013/12/27 职场文书
高中生的自我鉴定范文
2014/01/24 职场文书
新书吧创业计划书
2014/01/31 职场文书
团队经理竞聘书
2014/03/31 职场文书
2014世界杯球队球队口号
2014/06/05 职场文书
考察邀请函范文
2015/01/31 职场文书
《家世》读后感:看家训的力量
2019/12/30 职场文书
使用 JavaScript 制作页面效果
2021/04/21 Javascript