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 相关文章推荐
建立文件交换功能的脚本(三)
Oct 09 PHP
Windows中安装Apache2和PHP4权威指南
Nov 18 PHP
php格式化工具Beautify PHP小小BUG
Apr 24 PHP
php 购物车实例(申精)
May 11 PHP
PHP XML备份Mysql数据库
May 27 PHP
php读取html并截取字符串的简单代码
Nov 30 PHP
PHP学习之数组的定义和填充
Apr 17 PHP
php 解决旧系统 查出所有数据分页的类
Aug 27 PHP
thinkphp实现多语言功能(语言包)
Mar 04 PHP
php中运用http调用的GET和POST方法示例
Sep 29 PHP
PHP中上传多个文件的表单设计例子
Nov 19 PHP
thinkPHP3.2简单实现文件上传的方法
May 16 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写的获取各搜索蜘蛛爬行记录代码
2012/08/21 PHP
利用curl 多线程 模拟 并发的详解
2013/06/14 PHP
thinkPHP框架乐观锁和悲观锁实例分析
2019/10/30 PHP
第一个JavaScript入门基础 document.write输出
2010/02/22 Javascript
jQuery 过滤not()与filter()实例代码
2012/05/10 Javascript
jquery mobile事件多次绑定示例代码
2013/09/13 Javascript
使用Meteor配合Node.js编写实时聊天应用的范例
2015/06/23 Javascript
js中动态创建json,动态为json添加属性、属性值的实例
2016/12/02 Javascript
Bootstrap CSS布局之按钮
2016/12/17 Javascript
你可能不知道的JSON.stringify()详解
2017/08/17 Javascript
React如何利用相对于根目录进行引用组件详解
2017/10/09 Javascript
Mac中安装nvm的教程分享
2017/12/11 Javascript
微信小程序实现留言功能
2018/10/31 Javascript
javascript实现手动点赞效果
2019/04/09 Javascript
使用 vue 实现灭霸打响指英雄消失的效果附demo
2019/05/06 Javascript
解决layui动态添加的元素click等事件触发不了的问题
2019/09/20 Javascript
Vue.js中Line第三方登录api的实现代码
2020/06/29 Javascript
使用FastCGI部署Python的Django应用的教程
2015/07/22 Python
Python实现进程同步和通信的方法
2018/01/02 Python
Django 2.0版本的新特性抢先看!
2018/01/05 Python
python爬取淘宝商品销量信息
2018/11/16 Python
python+excel接口自动化获取token并作为请求参数进行传参操作
2020/11/10 Python
8款精美的CSS3表单设计(登录表单/下拉选择/按钮附演示及源码)
2013/02/04 HTML / CSS
CSS3 实现时间轴动画
2020/11/25 HTML / CSS
Bata印度官网:源自欧洲舒适鞋履品牌
2020/01/30 全球购物
最新党员的自我评价分享
2013/11/04 职场文书
创业计划书中包含的9个方面
2013/12/26 职场文书
动漫设计与制作专业推荐信
2014/07/07 职场文书
汽车技术服务与贸易专业求职信
2014/07/20 职场文书
2014年英语教学工作总结
2014/12/17 职场文书
毕业设计论文评语
2014/12/31 职场文书
高中教师个人总结
2015/02/10 职场文书
2015小学毕业班工作总结
2015/07/21 职场文书
golang 实现时间戳和时间的转化
2021/05/07 Golang
剖析后OpLog订阅MongoDB的数据变更就没那么难了
2022/02/24 MongoDB
十大经典日本动漫排行榜 海贼王第三,犬夜叉仅第八
2022/03/18 日漫