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

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                                   孙小瑞
时间: 2024-10-12 02:05:30

PHP学习笔记之数组排序及反向排序的相关文章

[oc学习笔记]数组的遍历和排序

1 //数组的遍历(可变数组举例) 2 //for遍历 3 NSMutableArray *aa = [NSMutableArray array]; 4 [aa addObjectsFromArray:@[@"ss",@"ddd",@"sad"]]; 5 for (int i = 0; i < aa.count; i++) { 6 NSLog(@"%@",[aa objectAtIndex:i]); 7 } 8 //快速

Java基础学习笔记 -- 10(数组排序)

1. 双层for循环 外层循环执行一次,内层循环会全部执行,总执行次数为"外层循环次数" * "内层循环次数". 案例31: 输出结果:         案例32: 2. 数组排序 1)冒泡排序 比较相邻的元素,将小的放到前面,大的放后面,比较一轮,会获取一个最大值在最后位置. 案例33: 输出结果: 2)冒泡排序--轻泡上浮 将最小的数字往前排,比较一轮,获取一个最小的在前面. 案例34: 输出结果: 3)插入排序 将数组中每个元素(从第二个元素开始的元素)与第一

算法(第四版)学习笔记之java实现希尔排序

希尔排序思想:使数组中任意间隔为h的元素都是有序的.希尔排序是插入排序的优化,先对数组局部进行排序,最后再使用插入排序将部分有序的数组排序. 代码如下: /** * * @author seabear * */ public class ShellSort { public static void sort(Comparable[] a) { int N = a.length; int h = 1; while(h < N/2) { h = 4 * h + 1; } while(h >= 1)

Hadoop学习笔记—11.MapReduce中的排序和分组

一.写在之前的 1.1 回顾Map阶段四大步凑 首先,我们回顾一下在MapReduce中,排序和分组在哪里被执行: 从上图中可以清楚地看出,在Step1.4也就是第四步中,需要对不同分区中的数据进行排序和分组,默认情况下,是按照key进行排序和分组. 1.2 实验场景数据文件 在一些特定的数据文件中,不一定都是类似于WordCount单次统计这种规范的数据,比如下面这类数据,它虽然只有两列,但是却有一定的实践意义. 3 3 3 2 3 1 2 2 2 1 1 1 (1)如果按照第一列升序排列,当

算法(第四版)学习笔记(二)——初级排序算法

时间复杂度(Time Complexity): 总运算次数表达式中受n的变化影响最大的那一项(不含系数)(注:若算法中语句执行次数为一个常数,则时间复杂度为O(1)) 若T(n)/f(n)求极限可得到一常数c,则时间复杂度T(n)=O(f(n)). 一个算法中的语句执行次数称为语句频度或时间频度.记为T(n) 算法的基本操作重复执行的次数是模块n的某一个函数f(n) 随着模块n的增大,算法执行的时间的增长率和f(n)的增长率成正比,所以f(n)越小,算法的时间复杂度越低,算法的效率越高. 空间复

算法(第四版)学习笔记之java实现选择排序

选择排序步骤: 1.找到数组中参与遍历比较的所有元素中的最小元素的下标: 2.将最小元素与数组中参与遍历比较的第一个元素进行交换(如果第一个元素就是最小元素的话,那么也会进行一次交换): 3.若数组中还有需要参与遍历比较的元素,则跳转到步骤1:否则排序结束. 在算法第四版中给出的所有排序均是适用于任意实现了Comparable接口的数据类型,若要将数字作为测试用例,请勿使用基本数据类型,改用Integer等实现了Comparable接口的对象. 选择排序代码如下: /** * * @author

IOS 学习笔记 2015-04-15 控制器数据反向传值

// // FirstViewController.h // 控制器数据传递 // // Created by wangtouwang on 15/4/15. // Copyright (c) 2015年 wangtouwang. All rights reserved. // #import <UIKit/UIKit.h> @interface FirstViewController : UIViewController @end // // FirstViewController.m //

算法导论学习笔记:2.1-插入排序

不假思索的写出这样的代码: /*N:数组长度*/ for (i = 1; i < N; i++){ int t = i; while (t > 0?a[t]<a[t-1]:0){ int k = a[t]; a[t] = a[t - 1]; a[t - 1] = k; t = t - 1; } } 不停与前一个元素比较,如果顺序不对那么交换:如果顺序对了,那么原a[i]里的元素已经找到了位置.a[0..i-1]的元素都是有序的,也就是书中所谓的“循环不变式”. 另:while循环中的表达

java排序学习笔记

前面写了js的排序实现,总得玩玩java的哈. 同样,冒泡.选择.快速(这三个之前实现过也写过文章).堆排序,然后做比较. 主要遇到的难点: - -||想轻松点写个封装计时的逻辑,不想每调用一个排序就要写一个计时代码.想想,还是javascript写起来方便: java的话,我想到的方法是写一个抽象类:抽象出排序方法,实现一个排序计时方法(该方法调用了抽象排序,但在先后排序时加入计时代码[感觉像是aop操作]): 接着所有排序类都继承这个抽象类,并实现排序方法,调用的时候直接调用继承的排序计时方