PHP 数组排序

使用 PHP 来编程已经有三四年了,但从来没有总结过其对数组的排序方式有多少种,一般都是在需要用到时才会在意,实在记不起有那些可用的内置函数时,就去搜索、查看文档。这种方法当然可以,要不然我也混不到现在。但这有个不好的地方,因为这显得对这些知识有些被动,对知识也不能够很系统地掌握。这样子说吧,每次当我去搜索时,搜索引擎都会返回各种各样的结果来给我,一般情况下,它返回的结果都是可行的。可是,对于我当时的具体需求,它提供给我的方案是最好的吗,或者那个是最好的、最符合我当时需求的呢?这个不是搜索就能解决的,这个需要平时的积累、思考!!

我想,以上就是我要写这篇文章的缘由吧。

PHP 有一些用来排序数组的函数, 主要区别有:

  • 有些函数基于 array 的键来排序, 而其他的基于值来排序的:$array['key'] = 'value';。
  • 排序之后键和值之间的关联关系是否能够保持, 是指排序之后数组的键可能 会被重置为数字型的(0,1,2 ...)。
  • 排序的顺序有:字母表顺序, 由低到高(升序), 由高到低(降序),数字排序,自然排序,随机顺序或者用户自定义排序。
  • 注意:下列的所有排序函数都是直接作用于数组本身, 而不是返回一个新的有序的数组。
  • 以下函数对于数组中相等的元素,它们在排序后的顺序是未定义的。 (也即相等元素之间的顺序是不稳定的)。
排序函数属性
函数名称 排序依据 数组索引键保持 排序的顺序
array_multisort() 键值关联的保持,
数字类型的不保持
第一个数组或者由选项指定
asort() 由低到高
arsort() 由高到低
krsort() 由高到低
ksort() 由低到高
natcasesort() 自然排序,大小写不敏感
natsort() 自然排序
rsort() 由高到低
shuffle() 随机
sort() 由高到低
uasort() 由用户定义
uksort() 由用户定义
usort() 由用户定义

这些函数大部分都比较容易理解,比较难理解的函数可能是 array_multisort() 和那三个用户定义比较函数的排序函数,稍候会详细分析这几个函数的用法。

排序类型标记

查看以上排序函数的原型可以发现,大部分都会有一个可选的参数“[, int $sort_flags = SORT_REGULAR ]”,它表示要按照什么数据类型来对数据进行排序。它可选的值及含义如下所示:

  • SORT_REGULAR - 正常比较单元(不改变类型)
  • SORT_NUMERIC - 单元被作为数字来比较
  • SORT_STRING - 单元被作为字符串来比较
  • SORT_LOCALE_STRING -
    根据当前的区域(locale)设置来把单元当作字符串比较,可以用
    setlocale() 来改变。
  • SORT_NATURAL - 和 natsort() 类似对每个单元以“自然的顺序”对字符串进行排序。 PHP 5.4.0 中新增的。
  • SORT_FLAG_CASE - 能够与 SORT_STRING
    SORT_NATURAL 合并(OR 位运算),不区分大小写排序字符串。

函数 array_multisort()

bool array_multisort ( array &$arr [, mixed $arg = SORT_ASC [, mixed $arg = SORT_REGULAR [, mixed $... ]]] )

array_multisort() 可以用来一次对多个数组进行排序,或者根据某一维或多维对多维数组进行排序。

输入数组被当成一个表的列并以行来排序——这类似于 SQL 的 ORDER BY 子句的功能。第一个数组是要排序的主要数组。数组中的行(值)比较为相同的话就按照下一个输入数组中相应值的大小来排序,依此类推。

理解这个函数的关键是“输入数组被当成一个表的列并以行来排序”,为了更好的说明这一点,需要举些栗子。


// 首先伪造几个数组数据
$a	= array(1,92,1,78,79);
$b	= array(77,25,86,8,19);
$c	= array(6,16,92,21,89);

// 每个数组当作一个列输出
$row	= array();
foreach($a as $key => $val){
	$row[$key][]	= $a[$key];
	$row[$key][]	= $b[$key];
	$row[$key][]	= $c[$key];
}

echo "排序前的数据\n";
foreach($row as $val){
	foreach($val as $v){
		echo "\t".$v;
	}
	echo "\n";
}

// 排序
array_multisort($a,$b,$c);

$row	= array();
foreach($a as $key => $val){
	$row[$key][]	= $a[$key];
	$row[$key][]	= $b[$key];
	$row[$key][]	= $c[$key];
}

echo "排序后的数据\n";
foreach($row as $val){
	foreach($val as $v){
		echo "\t".$v;
	}
	echo "\n";
}

运行结果如下:

运行结果
运行结果

这个结果和上面的解析刚好吻合,每个数组作为一个列,数组中对应下标的数据作为行,然后按行排列。以第一个数组进行排序,如何第一个中有数据相同,则按下一个数组的数据进行排序,以此类推...

用户自定义的比较函数

有三个用户定义比较函数的排序函数,很明显,关键就在那个自定义的比较函数,也就是说,数据的比较规则是由该函数定义的。就看下其中一个的用法吧。


function cmp($a, $b)
{
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

$a = array(3, 2, 5, 6, 1);

echo "排序前的数据\n";
foreach ($a as $key => $value) {
    echo "\t$key: $value\n";
}

usort($a, "cmp");

echo "排序后的数据\n";
foreach ($a as $key => $value) {
    echo "\t$key: $value\n";
}

运行结果如下:

运行结果
运行结果

可以看出,比较函数需要两个参数。在函数里面判断这两个参数的关系,相等则返回 0,第一个参赛比第二个大则返回 1,反之返回 -1。

THE END

本文作者: chenishr

本文标题:《PHP 数组排序》

本文地址: http://blog.chenishr.com/?p=508

©版权所有,除非注明, 永在路上文章均为原创,转载请以链接形式注明出处和作者细信息。

发表评论

电子邮件地址不会被公开。 必填项已用*标注