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 array_intersect()函数使用代码
Jan 14 PHP
深入理解PHP中的Session和Cookie
Jun 21 PHP
Codeigniter+PHPExcel实现导出数据到Excel文件
Jun 12 PHP
php实现的支持imagemagick及gd库两种处理的缩略图生成类
Sep 23 PHP
php使用function_exists判断函数可用的方法
Nov 19 PHP
smarty模板引擎从配置文件中获取数据的方法
Jan 22 PHP
PHP实现在线阅读PDF文件的方法
Jun 23 PHP
解决yii2左侧菜单子级无法高亮问题的方法
May 08 PHP
PHP实现RTX发送消息提醒的实例代码
Jan 03 PHP
/etc/php-fpm.d/www.conf 配置注意事项
Feb 04 PHP
php实现遍历文件夹的方法汇总
Mar 02 PHP
PHP从零开始打造自己的MVC框架之类的自动加载实现方法详解
Jun 03 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 empty函数 使用说明
2009/08/10 PHP
PHP下常用正则表达式整理
2010/10/26 PHP
网站用php实现paypal整合方法
2010/11/28 PHP
PHP与C#分别格式化文件大小的代码
2011/05/14 PHP
CodeIgniter使用phpcms模板引擎
2013/11/12 PHP
php两种无限分类方法实例
2015/04/21 PHP
用PHP代码在网页上生成图片
2015/07/01 PHP
php无限级分类实现方法分析
2016/10/19 PHP
php删除txt文件指定行及按行读取txt文档数据的方法
2017/01/30 PHP
Aster vs Newbee BO5 第一场2.19
2021/03/10 DOTA
jQuery UI 实现email输入提示实例
2013/08/15 Javascript
javascript中动态加载js文件多种解决办法总结
2013/11/15 Javascript
实例讲解js验证表单项是否为空的方法
2016/01/09 Javascript
jQuery实现图片加载完成后改变图片大小的方法
2016/03/29 Javascript
jQuery实现获取h1-h6标题元素值的方法
2017/03/06 Javascript
JS使用插件cryptojs进行加密解密数据实例
2017/05/11 Javascript
vue页面使用阿里oss上传功能的实例(二)
2017/08/09 Javascript
解决vue 界面在苹果手机上滑动点击事件等卡顿问题
2018/11/27 Javascript
js的各种数据类型判断的介绍
2019/01/19 Javascript
深入理解Vue keep-alive及实践总结
2019/08/21 Javascript
通过js实现压缩图片上传功能
2020/02/25 Javascript
[01:43]深扒TI7聊天轮盘语音出处4
2017/05/11 DOTA
pygame学习笔记(4):声音控制
2015/04/15 Python
Python RuntimeError: thread.__init__() not called解决方法
2015/04/28 Python
python写入中英文字符串到文件的方法
2015/05/06 Python
初步剖析C语言编程中的结构体
2016/01/16 Python
python实现一组典型数据格式转换
2018/12/15 Python
Python3简单爬虫抓取网页图片代码实例
2019/08/26 Python
Scrapy爬虫文件批量运行的实现
2020/09/30 Python
css3实现二维码扫描特效的示例
2020/10/29 HTML / CSS
劳动工资科岗位职责范本
2014/03/02 职场文书
2014年残联工作总结
2014/11/21 职场文书
中学教师个人总结
2015/02/10 职场文书
幼儿园中班教育随笔
2015/08/14 职场文书
2015年十月一日放假通知
2015/08/18 职场文书
简单谈谈Python面向对象的相关知识
2021/06/28 Python