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 相关文章推荐
Zend的MVC机制使用分析(一)
May 02 PHP
thinkphp文件处理类Dir.class.php的用法分析
Dec 08 PHP
php实现求相对时间函数
Jun 15 PHP
PHP配置把错误日志以邮件方式发送方法(Windows系统)
Jun 23 PHP
php简单生成随机数的方法
Jul 30 PHP
在Mac OS上搭建Nginx+PHP+MySQL开发环境的教程
Dec 21 PHP
PHP 匿名函数与注意事项详细介绍
Nov 26 PHP
php中this关键字用法分析
Dec 07 PHP
PHP实现的随机红包算法示例
Aug 14 PHP
PHP调用API接口实现天气查询功能的示例
Sep 21 PHP
PHP面向对象程序设计模拟一般面向对象语言中的方法重载(overload)示例
Jun 13 PHP
Yii框架连表查询操作示例
Sep 06 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对MySQL的缓冲查询和无缓冲查询
2016/07/01 PHP
ThinkPHP实现静态缓存和动态缓存示例代码
2017/05/02 PHP
Yii2.0框架实现带分页的多条件搜索功能示例
2019/02/20 PHP
IE autocomplete internet explorer's autocomplete
2007/06/30 Javascript
JavaScript高级程序设计阅读笔记(十六) javascript检测浏览器和操作系统-detect.js
2012/08/14 Javascript
jquery在项目中做复选框时遇到的一些问题笔记
2013/11/17 Javascript
JS画线(实例代码)
2013/11/20 Javascript
jquery缓动swing liner控制动画过程不同时刻的速度
2014/05/29 Javascript
JavaScript Promise启示录
2014/08/12 Javascript
PHP PDO操作总结
2014/11/17 Javascript
MVVM模式中ViewModel和View、Model有什么区别?
2015/06/19 Javascript
Bootstrap Paginator分页插件使用方法详解
2016/05/30 Javascript
原生JS版和jquery版实现checkbox的全选/全不选/点选/行内点选(Mr.Think)
2016/10/29 Javascript
jQuery动态添加.active 实现导航效果代码思路详解
2017/08/29 jQuery
BootStrap 标题设置跨行无效的解决方法
2017/10/25 Javascript
NodeJS模块与ES6模块系统语法及注意点详解
2019/01/04 NodeJs
小程序中this.setData的使用和注意事项
2019/08/28 Javascript
解决vue项目运行提示Warnings while compiling.警告的问题
2020/09/18 Javascript
详解python中 os._exit() 和 sys.exit(), exit(0)和exit(1) 的用法和区别
2017/06/23 Python
Python探索之URL Dispatcher实例详解
2017/10/28 Python
python编程使用selenium模拟登陆淘宝实例代码
2018/01/25 Python
Python2.7 实现引入自己写的类方法
2018/04/29 Python
对python3 urllib包与http包的使用详解
2018/05/10 Python
Python实现打砖块小游戏代码实例
2019/05/18 Python
python 判断linux进程,并杀死进程的实现方法
2019/07/01 Python
Python坐标线性插值应用实现
2019/11/13 Python
灵活运用CSS3特性绘制简易版围棋效果
2016/09/28 HTML / CSS
科颜氏加拿大官方网站: Kiehl’s加拿大
2016/08/16 全球购物
趣天网日本站:Qoo10 JP
2019/09/18 全球购物
乌克兰的第一家手表店:Deka
2020/03/05 全球购物
alice McCALL官网:澳大利亚时尚品牌
2020/11/16 全球购物
员工安全生产承诺书
2014/05/22 职场文书
社区精神文明建设汇报材料
2014/08/17 职场文书
交通处罚决定书
2015/06/24 职场文书
解决Pytorch dataloader时报错每个tensor维度不一样的问题
2021/05/28 Python
redis中lua脚本使用教程
2021/11/01 Redis