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文件上传表单摘自drupal的代码
Feb 15 PHP
php+ajax做仿百度搜索下拉自动提示框(有实例)
Aug 21 PHP
更改localhost为其他名字的方法
Feb 10 PHP
php设置允许大文件上传示例代码
Mar 10 PHP
php去除数组中重复数据
Nov 18 PHP
Laravel 5 框架入门(四)完结篇
Apr 09 PHP
php数组索引与键值操作技巧实例分析
Jun 24 PHP
PHP的Yii框架中移除组件所绑定的行为的方法
Mar 18 PHP
php禁用函数设置及查看方法详解
Jul 25 PHP
验证坐标在某坐标区域内php代码
Oct 08 PHP
详细解读php的命名空间(二)
Feb 21 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
Mar 26 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利用cookie实现访问次数统计代码
2011/05/19 PHP
Zend Framework教程之响应对象的封装Zend_Controller_Response实例详解
2016/03/07 PHP
使用PHP+MySql+Ajax+jQuery实现省市区三级联动功能示例
2017/09/15 PHP
PHP Include文件实例讲解
2019/02/15 PHP
JavaScript 放大镜 移动镜片效果代码
2011/05/09 Javascript
Jquery显示和隐藏元素或设为只读(含Ligerui的控件禁用,实例说明介绍)
2013/07/09 Javascript
JS上传图片前实现图片预览效果的方法
2015/03/02 Javascript
js事件监听器用法实例详解
2015/06/01 Javascript
js实现不提交表单获取单选按钮值的方法
2015/08/21 Javascript
JavaScript驾驭网页-获取网页元素
2016/03/24 Javascript
Jquery为DIV添加click事件的简单实例
2016/06/02 Javascript
jQuery 翻页组件yunm.pager.js实现div局部刷新的思路
2016/08/11 Javascript
TableSort.js表格排序插件使用方法详解
2017/02/10 Javascript
vue.js利用Object.defineProperty实现双向绑定
2017/03/09 Javascript
新手必须知的Node.js 4个JavaScript基本概念
2018/09/16 Javascript
JS实现返回上一页并刷新页面的方法分析
2019/07/16 Javascript
Layui 解决表格异步调用后台分页的问题
2019/10/26 Javascript
[38:39]完美世界DOTA2联赛循环赛 IO vs GXR BO2第二场 11.04
2020/11/05 DOTA
从零学python系列之从文件读取和保存数据
2014/05/23 Python
Python实现在Linux系统下更改当前进程运行用户
2015/02/04 Python
Python爬虫利用cookie实现模拟登陆实例详解
2017/01/12 Python
Python利用ElementTree模块处理XML的方法详解
2017/08/31 Python
django ajax json的实例代码
2018/05/29 Python
python实现textrank关键词提取
2018/06/22 Python
使用Python为中秋节绘制一块美味的月饼
2019/09/11 Python
tensorflow 限制显存大小的实现
2020/02/03 Python
tensorflow2.0与tensorflow1.0的性能区别介绍
2020/02/07 Python
HTML5 Canvas 起步(1) - 基本概念
2009/05/12 HTML / CSS
HTML5新增元素如何兼容旧浏览器有哪些方法
2014/05/09 HTML / CSS
HTML5 source标签:媒介元素定义媒介资源
2018/01/29 HTML / CSS
String这个类型的class为何定义成final?
2012/11/13 面试题
中学教师岗位职责
2013/11/26 职场文书
启动仪式策划方案
2014/06/14 职场文书
考研英语复习计划
2015/01/19 职场文书
本科毕业论文致谢词
2015/05/14 职场文书
详解Java实现数据结构之并查集
2021/06/23 Java/Android