(基础篇)数组的详解与使用
1.1 什么是數組
一個標量變量就是一個用來存儲數值的命名區域。同樣,一個數組就是一個用來存儲一系列變量值的命名區域,因此,可以使用數組組織標量變量。
存儲在數組中的值稱為數組元素。每個數組元素有一個相關的索引(也稱為關鍵字),它可以用來訪問元素。在大多數編程語言中,數組都具有數字索引,而且這些索個通常是從0或1開始的。
?
1.2 數字索引數組
在PHP中,數字索引的默認值是從0開始的,當然也可以改變它。
?
1.2.1 數字索引數組的初始化
$porducts = array( 'Tires', 'Oil', 'Spark Plugs' );
就像echo語句一樣,array()實際上是一個語言結構,而不是一個函數。
根據對數組內容的需求不同,可能不需要再像以上例子一樣對它們進行手工的初始化操作。如果所需數據保存在另一個數組中,可以使用運算符“=”簡單地將數組復制到另一個數組。
如果需要將按升序排列的數字保存在一個數組中,可以使用range()函數自動創建這個數組。如下這行代碼將創建一個從1到10的數字數組:$numbers = range(1,10);
range()函數具有一個可選的第三個參數,這個參數允許設定值之間的步驟。例如,如需建立一個1到10之間的奇數數組,可以使用如下代碼:$odds = range(1,10,2);
range()函數也可以對字符進行操作,如:$letters = range('a', 'z');
?
1.2.2 訪問數組的內容
要訪問一個變量的內容,可以直接使用其名稱。如果該變量是一個數組,可以使用變量名稱和關鍵字或索引的組合來訪問其內容。關鍵字或索引將指定我們要訪問的變量。索引在變量名稱后面用方括號括起來。
在默認的情況下,0元素是數組的第一個元素。
請注意,雖然PHP的字符串解析功能非常強大和智能,但是可能會引起混淆。當你將數組或其他變量嵌入雙引號中的字符串時,如果不能正確解釋它們,可以將它們放置在雙引號之外,或者查找第4章的“字符串操作與正則表達式”獲得更復雜的語法。
就像PHP的其他變量一樣,數組不需要預先初始化或創建。在第一次使用它們的時候,它們會自動創建。
?
1.2.3. 使用循環訪問數組
由于數組使用有序的數字作為索引,所以使用一個for循環就可以很容易地顯示數組的內容。
for ($i=0; $i<3; $i++)
echo "$products[$i]";
使用一個簡單的循環就可以訪問每個元素是數字索引數組的一個非常好的特性。也可以使用foreach循環,這個循環語句是專門為數組而設計的。如:
foreach ($products as $current)
echo $current. ' ';
?
1.3 使用不同索引的數組
PHP還支持相關數組。在相關數組中,可以將每個變量值與任何關鍵字或索引關聯起來。
?
1.3.1 初始化相關數組
如下所示的代碼可以創建一個以產品名稱作為關鍵字、以價格作為值的相關數組:
$prices = array( 'Tires'=>100, 'Oil'=>10, 'Spark Plugs'=>4 );
關鍵字和值之間的符號只是一個大于號與等于符號。
?
1.3.2 訪問數組元素
同樣,可以使用變量名稱和關鍵字來訪問數組的內容。例如$prices['Tires']。
?
1.3.3 使用循環語句
因為相關數組的索引不是數字,因此無法在for循環語句中使用一個簡單的計數器對數組進行操作。但是可以使用foreach循環或list()和each()結構。
當使用foreach循環語句對相關數組進行操作時,foreach()循環具有不同的結構??梢园慈缦路绞绞褂藐P鍵字:
foreach ($prices as $key => $value)
echo $key.'=>'.$value.'<br />';
如下所示的代碼將使用each()結構打印$prices數組的內容:
while( $element = each($prices))
{
echo $element['key'];
echo ' - ';
echo $element['value'];
echo '<br />';
}
each()函數將返回數組的當前元素,并將下一個元素作為當前元素。因為在while循環中調用each()函數,它將按順序返回數組中每個元素,并且當它到達數組末尾時,循環操作將終止。
在 這段代碼中,變量$element是一個數組。當調用each()時,它將返回一個帶有4個數值和4個指向數組位置的索引的數組。位置key和0包含了當 前元素的關鍵字,而位置value和1包含了當前元素的值。雖然這與選哪一種方法沒什么不同,但我們選擇了使用命名位置,而不是數字索引位置。
此外,還有一種更為高級和常見的方式來完成相同的操作。函數list()可以用來將一個數組分解為一系列的值??梢园凑杖缦路绞綄⒑瘮礶ach()返回的兩個值分開:list( $product, $price) = each( $price);
以上代碼使用each()從$prices數組中取出當前元素,并且將它作為數組返回,然后再指向下一個元素。它還使用list()將從each()返回的數組中所包含0、1兩個元素變為兩個名為$product和$price的新蠻量。
我們可以循環遍歷整個$prices數組,使用如下所示的簡短腳本顯示它的內容:
while(list($prodct, $pirce) = each($prices))
echo "$product - $price<br />";
這段代碼的輸出結果與前面腳本的輸出結果相同,但它更容易閱讀,因為list()允許為新變量命名。
需要注意的一點是,當使用each()函數時,數組將記錄當前元素。如果希望在相同的腳本中兩次使用該數組,就必須使用函數reset()將當前元素重新設置到數組開始處。要再次遍歷prices數組,可以使用如下所示的代碼:
reset($prices);
while(list($product, $price) = each($prices))
echo "$product - $price<br />";
?
1.4 數組操作符
+聯合,==等價,===恒等,!=不等價,<>不等價,!==不恒等。
聯合操作符嘗試將$b中的元素添加到$a的末尾。如果$b中的元素與$a中的一些元素具有相同的索引,它們將不會被添加。即$a中的元素將不會被覆蓋。
?
1.5 多維數組
數組不一定就是一個關鍵字和值的簡單列表——數組中的每個位置還可以保存另一個數組。使用這種方法,可以創建一個二維數組??梢园讯S數組當成一個矩陣,或者是一個具有寬度和高度或者行和列的網絡。
?
1.6 數組排序
?
1.6.1 使用sort()函數
sort()函數是區分字母大小寫的。所有的大家字母都在小寫字母的前面。所以‘A’小于‘Z’,而'Z'小于‘a’。
該 函數的第二個參數是可選的。這個可選參數可以傳遞SORT_REGULAR(默認值)、SORT_NUMERIC或SORT_STRING。指定排序類型 的功能是非常有用的,例如,當要比較可能包含有數字2和12的字符串時。從數學角度看,2要小于12,但是作為字符串,‘12’卻要小于‘2’。
?
1.6.2 使用asort()函數和ksort()函數對相關數組排序
函數asort()根據數組的每個元素值進行排序。ksort()函數是按關鍵字排序而不是按值排序。
?
1.6.3 反向排序
函數rsort()將一個一維數字索引數組按降序排序。函數arsort()將一個一維相關數組按每個元素值的降序排序。函數krsort()針根據數組元素的關鍵字將一維數組按照降序排序。
為了訪問一個一維數組中的數據,需要使用數組的名稱和元素的索引,除了一個元素具有兩個索引——行和列外,二維數組和一維數組是類似的。
可以使用雙重for循環來實現同樣的效果:
for ( $row=0; $row<3; $row++ )
{
for ( $column=0; $column<3; $column++ )
{
echo '|'.$products[$row][$column];
|
echo '|<br />';
}
如果對一個大數組使用這種代碼,那么將簡潔得多。
你可能更喜歡創建列名稱來代替數字??梢允褂萌缦麓a:
$products = array ( array ( 'Code'=>'TIR', 'Descrīption'=>'Tires', 'Price'=>100 ), array ( 'Code'=>'OIL', 'Descrīption'=>'Oil', 'Price'=>10 ), array ( 'Code'=>'SPK', 'Descrīption'=>'Spark Plugs', 'Price'=>4 ) };
如果希望檢索單個值,那么使用這個數組會容易得多。請記住,將所描述的內容保存到用它的名 稱命名的列中,與將其保存到所謂的第一列中相比,前者更容易記憶。使用描述性索引,不需要記住某個元素是存放在[x][y]位置的。使用一對有意義的行和 列的名稱作為索引可以使用你很容易找到所需的數據。
然后,我們卻不能使用一個簡單的for循環按順序遍歷每一列??梢允褂胒or循環遍歷外部的數 字索引數組$products。$products數組的每一行都是一個具有描述性索引的數組。在while循環中使用each()和list()函數, 可以遍歷整個內部數組。因此,需要一個內嵌有while循環的for循環。
for ( $row = 0; $row < 3; $row++ }
{
while ( list ( $key, $value ) = each ( $products[$row] ) )
{
echo "|$value";
}
echo '|<br />';
}
?
三維數組具有高、寬、深的概念。如果能輕松地將一個二維數組想像成一個有行和列的表格,那么就可以將三維數組想像成一堆像這樣的表格。每個元素可以通過層、行和列進行引用。
根據創建多維數組的方法,可以創建四維、五維或六維數組。在PHP中,并沒有設置數組維數的限制,但人們很難設想一個多于三維的數組。大多數的實際問題在邏輯上只需要使用三維或者更少維的數組結構就可以了。
?
1.7 多維數組的排序
對 多于一維的數組進行排序,或者不按字母和數字的順序進行排,要復雜得多。PHP知道如何比較兩個數字或字符串,但在多維數組中,每個元素都是一個數組。 PHP不知道如何比較兩個數組,所以需要建立一個比較它們的方法。在大多數情況下,單詞和數字的順序是顯而易見的——但對于復雜的對象,問題就會多一些。
?
1.7.1 用戶定義排序
usort()中的“u”代表“user”,因為這個函數要求傳入用戶定義的比較函數。asort和ksort對應的版本uasort()和uksort()也要求傳入用戶定義的比較函數。
類似于asort(),當對非數字索引數組的值進行排序時,uasort()才會被使用。如果值是簡單的數字或文本則可以使用asort。如果要比較的值像數組一樣復雜,可以定義一個比較函數,然后使用uasort()。
類似于ksort(),當對非數字索引數組的關鍵字進行排序時才使用uksort()。如果值是簡單的數字或文本就使用ksort。如果要比較的對象像數組一樣復雜,可以定義一個比較函數,然后使用uksort()。
?
1.7.2 反向用戶排序
函數sort()、asort()和ksort()都分別對應一個帶字母“r”的反向排序函數。用戶定義的排序沒有反向變體,但可以對一個多維數組進行反向排序。
?
1.8 對數組進行重新排序
?
1.8.1 使用shuffle()函數
在PHP的早期版本中,shuffle()要求調用srand()函數時首先提供一個隨機數生成器。如今,這個步驟已經不再需要了。
如果這個函數對你非常重要,可以在程序中應用該函數之前在服務器上測試它。
由于并不需要真正重新排序整個數組,使用array_rand()函數可以實現相同的功能。
?
1.8.2 使用array_reverse()函數
array_reverse()函數使用一個數組作參數,返回一個內容與參數數組相同但順序相反的數組。
因為單獨使用range()函數將創建一個升序序列,所以必須使用sort()函數或array_reverse()函數將數組中的數字變為降序?;蛘?#xff0c;也可以使用for循環通過一次一個元素的方式創建這個數組。如:
$numbers = array();
for ($i=10; $i>0; $i--)
array_push( $numbers, $i );
一個for循環可以像這樣按降序方式運行。可以將計數器
一個for循環可以像這樣按降序方式運行??梢詫⒂嫈灯鞯某跏贾翟O為一個大數,在每次循環末尾使用運算符“--”將計數器減1。
在這里,我們創建了一個空數組,然后使用array_push()函數將每個新元素添加到數組的末尾。請注意,和array_push()相反的函數是array_pop(),這個函數用來刪除并返回數組末尾的一個元素。
或者,也可以使用array_reverse()函數將由range()函數所創建的數組進行反向排序。
請注意,array_reverse()函數將返回一個原數組修改后的副本。如果不再需要原來的數組,比如在這個例子中,可以用新的副本覆蓋原來的版本。
如果數據只是一系列的整數,可以通過將-1作為range()函數的第三個可選調參數,以相反的順序創建該數組。
?
1.9 從文件載入數組
使用file()函數將整個文件載入一個數組中。文件中的每行則成為數組中的一個元素。使用了count()函數來統計數組中的元素個數。
explode("\t", $orders[$i])
explode()函數可以將傳入的字符串分割成一個個小塊。每個制表符成為兩個元素之間的斷點。這個函數的可選參數limit可以用來限制被返回的最大塊數。
可以使用許多方法從字符串中提取數字。在這里,我們使用了intval()函數。它可以將一個字符串轉化成一個整數。這個轉換是相當智能化的,它可以忽略某些部分,例如標簽就不能轉換成數字。
?
1.10 執行其他的數組操作
1.10.1 在數組中瀏覽:each()、current()、reset()、end()、next()、pos()和prev()
前面已經提到,每個數組都有一個內部指針指向數組中的當前元素。當使用函數each()時,就間接地使用了這個指針,但是也可以直接使用和操作這個指針。
如果創建一個新數組,那么當前指針就將被初始化,并指向數組的第一個元素。
調用next()或each()將使指針前移一個元素。調用each($array_name)會在指針前移一個位置之前返回當前元素。next()函數則有些不同——調用next($array_name)是將指針前移,然后再返回新的當前元素。
調用end($array_name)可以將指針移到數組末尾。
要反向遍歷一個數組,可以使用end()和prev()函數。prev()函數和next()函數相反。它是將當前指針往回移一個位置然后再返回新的當前元素。
?
1.10.2 對數組的每一個元素應用任何函數:array_walk()
array_walk()函數需要三個參數。第一個是arr,也就是需要處理的數組。第二個是func,也就是用戶自定義并將作用于數組中每個元素的函數。第三個參數userdata是可選的,如果使用它,它可以作為一個參數傳遞給我們自己的函數。
看一個銷微復雜點的例子:
function my_multiply(&$value, $key, $factor)
{
$value *= $factor;
}
array_walk(&$array, 'my_multiply', 3);
在這里,我們定義了一個名為my_multiply()的函數,它可以用所提供的乘法因子去乘以數組中的每個元素。
此外,還有一個需要注意的問題是傳遞毿數$value的方式。在my_multiply()的函數定義中,變量前面的地址符(&)意味著$value是按引用方式傳遞的。按引用方式傳遞允許函數修改數組的內容。
?
1.10.3 統計數組元素個數:count()、sizeof()和array_count_values()
count()函數和sizeof()函數具有同樣的用途,都可以返回數組元素的個數。可以得到一個常規標量變量中的元素個數,如果傳遞給這個函數的數組是一個空數組,或者是一個沒有經過設定的變量,返回的數組個數就是0。
如 果調用array_count_values($array),這個函數將會統計每個特定的值在數組$array中出現過的次數(這就是數組的基數集)。 這個函數將返回一個包含頻率表的相關數組。這個數組包含數組$array中的所有值,并以這些值作為相關數組的關鍵字。每個關鍵字所對應的數值就是關鍵字 在數組$array中出現的次數。
?
1.10.4 將數組轉換成標量變量:extract()
對于一個非數字索引數組,而該數組又有許多關鍵字-值對,可以使用函數extract()將它們轉換成一系列的標量變量。
函數extract()的作用是通過一個數組創建一系列的標量變量,這些變量的名稱必須是數組中關鍵字的名稱,而變量值則是數組中的值。
extract()函數具有兩個可選參數:extract_type和prefix。變量extract_type將告訴extract()函數如何處理沖突。有時可能已經存在一個和數組關鍵字同名的變量,該函數的默認操作是覆蓋已有的變量。
兩個最常用的選項是EXTR_OVERWRITE(默認值)和EXTR_PREFIX_ALL。當知道會發生特定的沖突并且希望跳過該關鍵字或要給它加上前綴時,可能會用到其他選項。
extract()可以提取出一個元素,該元素的關鍵字必須是一個有效的變量名稱,這就意味著以數字開始或包含空格的關鍵字將被跳過。
轉載于:https://www.cnblogs.com/zhangmiaomiao/p/6013122.html
總結
以上是生活随笔為你收集整理的(基础篇)数组的详解与使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【一周热门软件更新】我一口气发布六个版本
- 下一篇: Android性能优化工具