PHP学习笔记之数组排序及反向排序

元气小坏坏 提交于 2020-01-25 04:54:24

1、使用sort()对数组进行排序

sort()函数可以对字母进行排序,如:

$products=array('Tires','Oil','Spark Plugs');

sort($products);

现在,该数组所包含元素的顺序是:Oil、Spark Plugs、Tires。

还可以按数字顺序进行排序。如果具有一个包含了Bob产品价格的数组,就可以按数字升序进行排序,如下所示:

$prices=array(100,10,4);

sort($prices);

现在,产品价格的顺序将变成:4、10、100。

请注意,sort()函数是区分字母大小写的。所有大写字母都在小写字母的前面。所以A小于Z,而Z小于a。

该函数的第二个参数是可选的。这个可选参数可以传递SORT_REGULAR(默认值)、SORT_NUMERIC或SORT_STRING。指定排序类型的功能是非常有用的,例如,当要比较可能包含有数字2和12的字符串时。从数字角度看,2要小于12,但是作为字符串,'12'却要小于'2'。

 

2、使用asort()与ksort()对关联数组排序

 

如果用关联数组存储各个项目和它们的价格,就需要用不同的排序函数使关键字和值在排序时仍然保持一致。

 

如下所示的代码将创建一个包含3个产品及价格的数组,然后将它们按价格的升序进行排序:

 


 

$prices=array('Tires'=>100,'Oil'=>10,'Spark Plugs'=>4);

 

asort($prices);

 


 

函数asort()根据数组的每个元素值进行排序。在这个数组中,元素值为价格而关键字为文字说明。如果不是按价格排序而要按说明排序,就可以使用ksort()函数,它是按关键字排序而不是按值排序。这段代码会让数组的关键字按字母顺序排列——Oil、Spark Plugs、Tires:

 


 

$prices=array('Tires'=>100,'Oil'=>10,'Spark Plugs'=>4);

 

ksort($prices);

 

3、使用rsort(),arsort()以及krsort()函数对数组进行反向排序(降序)了解了sort()、asort()和ksort()。这3个不同的排序函数都使数组按升序排序。它们每个都对应有一个反向排序的函数,可以将数组按降序排序。实现反向排序的函数是rsort()、arsort()和krsort()。

反向排序函数与排序函数的用法相同。函数rsort()将一个一维数字索引数组按降序排序。函数arsort()将一个一维关联数组按每个元素值的降序排序。函数krsort()将根据数组元素的关键字将一维数组按照降序排序。

 

4、多维数组的排序对多于一维的数组进行排序,或者不按字母和数字的顺序进行排序,要复杂得多。PHP知道如何比较两个数字或字符串,但在多维数组中,每个元素都是一个数组。PHP不知道如何比较两个数组,所以需要建立一个比较它们的方法。在大多数情况下,单词和数字的顺序是显而易见的——但对于复杂的对象,问题就会多一些。

 

一.用户自定义排序
这里有一个前面使用过的二维数组定义。这个数组存储了Bob的3种产品的代码、说明和价格:

 

$product=array(    array('Code'=>'TIRE','Description'=>'Tires','Price'=>100),    array('Code'=>'OIL','Description'=>'Oil','Price'=>10),    array('Code'=>'SPARK','Description'=>'Spark Plugs','Price'=>200));

如果对这个数组进行排序,最后的顺序会是怎样呢?因为我们知道各个数组内容所代表的意义,所以至少会有两种有用的排序方法。我们可能对产品的说明按字母排序,或者对价格按大小排序。两种结果都有可能,但需要用函数usort()告诉PHP如何比较各个元素。要实现此功能,需要编写自己的比较函数。

注:usort()函数使用用户自定义的函数对数组排序。

语法

usort(array,"function")
参数描述
array 必需。规定要排序的数组。
function

必需。用户自定义的函数。

函数必须设计为返回 -1, 0, 或 1,并应该接受两个供比较的参数,同时以类似下面这样的方式来工作:

  • 如果 a = b, 返回 0
  • 如果 a > b, 返回 1
  • 如果 a < b, 返回 -1

如下所示的代码对订单数组中的第二列(说明),按字母进行排序:

function compare($x,$y){    if($x[1]==$y[1]){        return 0;    }else if($x[1]<$y[1]){        return -1;    }else{        return 1;    }}usort($product,"compare");
我们用关键词function定义一个函数。需要给出函数的名称,而且该名称应该有意义,例如在这个例子中,函数被命名为compare()。许多函数都带有参数。compare()函数有两个参数:一个为$x,另一个为$y。该函数的作用是比较两个值的大小。

在这个例子中,$x和$y将是主数组中的两个子数组,分别代表一种产品。因为计数是从0开始的,说明字段是这个数组的第二个元素,所以为了访问数组$x的说明字段,需要输入$x[1]和$y[1]来比较两个传递给函数的数组的说明字段。


当一个函数结束的时候,它会给调用它的代码一个答复。该答复称为返回值。为了返回一个值,在函数中使用关键词return。例如,return 1;该语句将数值1返回给调用它的代码。

为了能够被usort()函数使用,compare()函数必须比较$x和$y。如果$x等于$y,该函数必须返回0,如果$x小于$y,该函数必须返回负数,而如果大于,则返回一个正数。根据$x和$y的值,该函数将返回0、1或-1。

以上代码的最后一行语句调用了内置函数usort(),该函数使用的参数分别是希望保存的数组($products)和比较函数的名称(compare())。

如果要让数组按另一种顺序存储,只要编写一个不同的比较函数。要按价格进行排序,就必须查看数组的第三列,从而创建如下所示的比较函数:

function compare($x,$y){    if($x[2]==$y[2]){        return 0;    }else if($x[2]<$y[2]){        return -1;    }else{        return 1;    }}当调用usort($products,'$compare')的时候,数组将按价格的升序来排序。注意:当你通过运行这些代码来测试时,这些代码将不产生任何输出。这些代码只是将编写的大部分代码中的一部分。usort()中的"u"代表"user",因为这个函数要求传入用户定义的比较函数。asort和ksort对应的版本uasort()和uksort()也要求传入用户定义的比较函数。

类似于asort(),当对非数字索引数组的值进行排序时,uasort()才会被使用。如果值是简单的数字或文本则可以使用asort。如果要比较的值像数组一样复杂,可以定义一个比较函数,然后使用uasort()。


类似于ksort(),当对非数字索引数组的关键字进行排序时才使用uksort()。如果值是简单的数字或文本就使用ksort。如果要比较的对象像数组一样复杂,可以定义一个比较函数,然后使用uksort()。

二、反向用户排序函数sort()、asort()和ksort()都分别对应一个带字母"r"的反向排序函数。用户定义的排序没有反向变体,但可以对一个多维数组进行反向排序。由于用户应该提供比较函数,因此可以编写一个能够返回相反值的比较函数。要进行反向排序,$x小于$y时函数需要返回1,$x大于$y时函数需要返回-1,这样就做成了一个反向排序。例如:
function reverse_compare($x,$y){    if($x[2]==$y[2]){        return 0;    }else if($x[2]<$y[2]){        return 1;    }else{        return -1;    }}

调用usort($products,'reverse_compare'),数组会按价格的降序来排序。

5、对数组进行重新排序

在一些应用程序中,可能希望按另一种方式式对数组排序。函数shuffle()将数组各元素进行随机排序。函数array_reverse()给出一个原来数组的反向排序

5.1 使用shuffle()函数

Bob想让其网站首页上的产品能够反映出公司的特色。他拥有许多产品,但希望能够从中随机地选出3种产品并显示在首页上。为了不至于让多次登录网站的访问者感到厌倦,他想让每次访问看到的3种产品都不同。如果将所有产品都存储在同一数组中,就很容易实现这个目标。通过打乱数组并按随机顺序排列,然后从中选出前3种产品,显示这3种产品的图片。

5.2 使用array_reverse()函数

array_reverse()函数使用一个数组作参数,返回一个内容与参数数组相同但顺序相反的数组。例如,可以使用很多方法创建一个按逆序包含数字10到1的数组。

因为单独使用range()函数将创建一个升序序列,所以必须使用rsort()函数或array_reverse()函数将数组中的数字变为降序。或者,也可以使用for循环通过一次一个元素的方式创建这个数组,如下所示:

$numbers=array();

for($i=10;$i>0;$i--){

array_push($numbers,$i);

}

一个for循环可以像这样按降序方式运行。可以将计数器的初始值设为一个大数,在每次循环末尾使用运算符“--”将计数器减1。

在这里,创建了一个空数组,然后使用array_push()函数将每个新元素添加到数组的末尾。请注意,和array_push()相反的函数是array_pop(),这个函数用来删除并返回数组末尾的一个元素。

或者,也可以使用array_reverse()函数将由range()函数所创建的数组进行反向排序。如下:

$numbers=range(1,10);

$numbers=array_reverse($numbers);

请注意,array_reverse()函数将返回一个原数组修改后的副本。如果不再需要原来的数组,比如在这个例子中,可以用新的副本覆盖原来的版本。

如果数据只是一系列的整数,可以通过将-1作为range()函数的第三个可选步调参数,以相反的顺序创建该数组,如下所示:

$numbers=range(10,1,-1);

 

“量变的积累总会产生质变,做不了贵族的后代就做贵族的祖先”——献给那些所有和我一样正在努力的人。                                2015-04-02                                   孙小瑞

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!