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