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 09 PHP
基于mysql的bbs设计(二)
Oct 09 PHP
PhpMyAdmin中无法导入sql文件的解决办法
Jan 08 PHP
从手册去理解分析PHP session机制
Jul 17 PHP
PHP实现异步调用方法研究与分享
Oct 27 PHP
计算php页面运行时间的函数介绍
Jul 01 PHP
PHP快速按行读取CSV大文件的封装类分享(也适用于其它超大文本文件)
Apr 10 PHP
php+mysql数据库实现无限分类的方法
Dec 12 PHP
PHP调用.NET的WebService 简单实例
Mar 27 PHP
PHP中应该避免使用同名变量(拆分临时变量)
Apr 03 PHP
php使用MySQL保存session会话的方法
Jun 18 PHP
Laravel修改验证提示信息为中文的示例
Oct 23 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源代码
2006/10/09 PHP
php中smarty实现多模版网站的方法
2015/06/11 PHP
在PHP程序中使用Rust扩展的方法
2015/07/03 PHP
PHP生成唯一订单号
2015/07/05 PHP
jquery 全局AJAX事件使用代码
2010/11/05 Javascript
使用jquery为table动态添加行的实现代码
2011/03/30 Javascript
js特效,页面下雪的小例子
2013/06/17 Javascript
jQuery 属性选择器element[herf*='value']使用示例
2013/10/20 Javascript
jQuery多项选项卡的实现思路附样式及代码
2014/06/03 Javascript
jQuery实现企业网站横幅焦点图切换功能实例
2015/04/30 Javascript
jQuery实现给页面换肤的方法
2015/05/30 Javascript
点评js异步加载的4种方式
2015/12/22 Javascript
省市联动效果的简单实现代码(推荐)
2016/06/06 Javascript
JSON 对象未定义错误的解决方法
2016/09/29 Javascript
JSON与XML的区别对比及案例应用
2016/11/11 Javascript
基于JavaScript实现熔岩灯效果导航菜单
2017/01/04 Javascript
angular.js+node.js实现下载图片处理详解
2017/03/31 Javascript
vue-cli2.9.3 详细教程
2018/04/23 Javascript
typescript nodejs 依赖注入实现方法代码详解
2019/07/21 NodeJs
vue选项卡切换登录方式小案例
2019/09/27 Javascript
详解vue 自定义组件使用v-model 及探究其中原理
2019/10/11 Javascript
[02:01]大师之路——DOTA2完美大师赛11月论剑上海
2017/11/06 DOTA
深入浅析Python字符编码
2015/11/12 Python
Python的缺点和劣势分析
2019/11/19 Python
Python序列类型的打包和解包实例
2019/12/21 Python
通过python检测字符串的字母
2020/02/18 Python
python利用faker库批量生成测试数据
2020/10/15 Python
CSS3径向渐变之大鱼吃小鱼之孤单的大鱼
2016/04/26 HTML / CSS
canvas绘制视频封面的方法
2018/02/05 HTML / CSS
Desigual英国官网:在线购买原创服装
2018/03/09 全球购物
德国游戏机商店:Konsolenkost
2019/12/08 全球购物
单位介绍信范文
2014/01/18 职场文书
工商企业管理应届生求职信
2014/05/04 职场文书
《鸟的天堂》教学反思
2016/02/19 职场文书
JS数组的常用方法整理
2021/03/31 Javascript
python多线程方法详解
2022/01/18 Python