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 MySQL与分页效率
Jun 04 PHP
php trim 去除空字符的定义与语法介绍
May 31 PHP
php中使用ExcelFileParser处理excel获得数据(可作批量导入到数据库使用)
Aug 21 PHP
PHP的变量总结 新手推荐
Apr 18 PHP
php和mysql中uft-8中文编码乱码的几种解决办法
Apr 19 PHP
openflashchart 2.0 简单案例php版
May 21 PHP
谈谈你对Zend SAPIs(Zend SAPI Internals)的理解
Nov 10 PHP
yii2超好用的日期组件和时间组件
May 05 PHP
PHP 传输会话curl函数的实例详解
Sep 12 PHP
PHP基于回溯算法解决n皇后问题的方法示例
Nov 07 PHP
Laravel核心解读之异常处理的实践过程
Feb 24 PHP
使用PHPWord生成word文档的方法详解
Jun 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的开合式多级菜单程序
2006/10/09 PHP
php 文件上传代码(限制jpg文件)
2010/01/05 PHP
约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
2010/10/12 PHP
PHP以指定字段为索引返回数据库所取的数据数组
2013/06/30 PHP
Laravel中使用自己编写类库的3种方法
2015/02/10 PHP
PHP并发查询MySQL的实例代码
2017/08/09 PHP
jquery弹出框的用法示例(一)
2013/08/26 Javascript
jquery删除指定的html标签并保留标签内文本内容的方法
2014/04/02 Javascript
Nodejs极简入门教程(三):进程
2014/10/27 NodeJs
第一次接触神奇的Bootstrap基础排版
2016/07/26 Javascript
工作中常用的js、jquery自定义扩展函数代码片段汇总
2016/12/22 Javascript
走进AngularJs之过滤器(filter)详解
2017/02/17 Javascript
vue2.0项目中使用Ueditor富文本编辑器示例代码
2017/08/14 Javascript
10个在JavaScript开发中常遇到的BUG
2017/12/18 Javascript
JavaScript检查数据中是否存在相同的元素(两种方法)
2018/10/07 Javascript
JavaScript面试技巧之数组的一些不low操作
2019/03/22 Javascript
layer 刷新某个页面的实现方法
2019/09/05 Javascript
Python采用socket模拟TCP通讯的实现方法
2014/11/19 Python
Python爬虫爬取美剧网站的实现代码
2016/09/03 Python
浅谈python numpy中nonzero()的用法
2018/04/02 Python
Python3实现购物车功能
2018/04/18 Python
django项目用higcharts统计最近七天文章点击量
2019/08/17 Python
pytorch下使用LSTM神经网络写诗实例
2020/01/14 Python
Python reversed函数及使用方法解析
2020/03/17 Python
Python %r和%s区别代码实例解析
2020/04/03 Python
如何解决python多种版本冲突问题
2020/10/13 Python
用CSS3实现Win8风格的方格导航菜单效果
2013/04/10 HTML / CSS
期末总结的个人自我评价
2013/11/02 职场文书
家居饰品店创业计划书
2014/01/31 职场文书
珍惜资源保护环境的建议书
2014/05/14 职场文书
2014年减负工作总结
2014/12/10 职场文书
工作简历自我评价
2015/03/11 职场文书
幼儿园六一主持词开场白
2015/05/28 职场文书
童年读书笔记
2015/06/26 职场文书
一文带你探究MySQL中的NULL
2021/11/11 MySQL
Mysql调整优化之四种分区方式以及组合分区
2022/04/13 MySQL