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
                                   孫小瑞

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM