PHP數組的進階遍曆和操作處理方法_PHP教程

來源:互聯網
上載者:User
前面我講過簡單的數組遍曆,這些基於foreach,for之類的語句,下面我來介紹數組的進階遍曆方法介紹,各位朋友可參考,這些數組才真用於開發實用效能強,複雜也更高了。

PHP對數組的處理可以稱為該語言最有吸引力的特性之一,它支援70多種數組相關的函數。不論你想翻轉一個數組、判斷某個值在數組中是否存在、將數群組轉換成一個字串還是計算數組的大小,僅僅執行一個現有的函數就可以完成。然而也有一些數組相關的任務對開發人員的要求就較高,僅僅知道手冊有某個功能是不能解決的,這些任務就需要對PHP的原始特性有一些深入的理解,還需要一些解決問題的想象力。

多維關聯陣列排序
PHP提供了一些數組排序的函數,比如sort(), ksort(),和asort(),但是卻沒有提供對多維關聯陣列的排序。


比如這樣的數組:

Array
(
[0] => Array
(
[name] => chess
[price] => 12.99
)

[1] => Array
(
[name] => checkers
[price] => 9.99
)

[2] => Array
(
[name] => backgammon
[price] => 29.99
)
)

要將該數組按照升序排序,你需要自己寫一個函數用於比較價格,然後將該函數作為回呼函數傳遞給usort()函數來實現該功能:

代碼如下 複製代碼

function comparePrice($priceA, $priceB){
return $priceA['price'] - $priceB['price'];
}

usort($games, 'comparePrice');

執行了該程式片段,數組就會被排序,結果如下所示:

Array
(
[0] => Array
(
[name] => checkers
[price] => 9.99
)

[1] => Array
(
[name] => chess
[price] => 12.99
)

[2] => Array
(
[name] => backgammon
[price] => 29.99
)
)

要將該數組按照降序排序,把comparePrice()函數裡面的兩個減的數調換位置就可以了。

逆序遍曆數組
PHP的While迴圈和For迴圈是遍曆一個數組最常用的方法。但是你怎樣遍曆像下面這個數組呢?

Array
(
[0] => Array
(
[name] => Board
[games] => Array
(
[0] => Array
(
[name] => chess
[price] => 12.99
)

[1] => Array
(
[name] => checkers
[price] => 9.99
)
)
)
)

PHP標準庫中有一個對集合的迭代器iterators類,它不僅僅能夠用於遍曆一些異構的資料結構(比如檔案系統和資料庫查詢結果集),也可以對一些不知道大小的嵌套數組的遍曆。比如對上面的數組的遍曆,可以使用RecursiveArrayIterator迭代器進行:

代碼如下 複製代碼

$iterator = new RecursiveArrayIterator($games);
iterator_apply($iterator, 'navigateArray', array($iterator));

function navigateArray($iterator) {
while ($iterator->valid()) {
if ($iterator->hasChildren()) {
navigateArray($iterator->getChildren());
} else {
printf("%s: %s", $iterator->key(), $iterator->current());
}
$iterator->next();
}
}

執行該段代碼會給出以下的結果:

name: Board
name: chess
price: 12.99
name: checkers
price: 9.99

過濾關聯陣列的結果
假定你得到了如下一個數組,但是你僅僅想操作價格低於$11.99的元素:

Array
(
[0] => Array
(
[name] => checkers
[price] => 9.99
)

[1] => Array
(
[name] => chess
[price] => 12.99
)

[2] => Array
(
[name] => backgammon
[price] => 29.99
)
)

使用array_reduce()函數可以很簡單的實現:

代碼如下 複製代碼

function filterGames($game){
return ($game['price'] < 11.99);
}

$names = array_filter($games, 'filterGames');

array_reduce()函數會過濾掉不滿足回呼函數的所有的元素,本例子的回呼函數就是filterGames。任何價格低於11.99的元素會被留下,其他的會被剔除。該程式碼片段的執行結果:

Array
(
[1] => Array
(
[name] => checkers
[price] => 9.99
)
)

對象轉換成數組
一個需求就是將對象轉換成數組形式,方法比你想象的簡單很多,僅僅強制轉換就可以了!例子:

代碼如下 複製代碼

class Game {
public $name;
public $price;
}

$game = new Game();
$game->name = 'chess';
$game->price = 12.99;

print_r(array($game));

執行該例子就會產生如下結果:

Array
(
[0] => Game Object
(
[name] => chess
[price] => 12.99
)
)

將對象轉換成數組會出現一些不可預料的副作用。比如上面的程式碼片段,所有的成員變數都是public類型的,但是對於private私人變數的返回結果會變得不一樣。下面是另外一個例子:

代碼如下 複製代碼

class Game {
public $name;
private $_price;

public function setPrice($price) {
$this->_price = $price;
}
}

$game = new Game();
$game->name = 'chess';
$game->setPrice(12.99);

print_r(array($game));執行該程式碼片段:

Array
(
[0] => Game Object
(
[name] => chess
[_price:Game:private] => 12.99
)
)

正如你所看到的,為了進行區分,數組中儲存的私人變數的key被自動改變了。

數組的“自然排序”
PHP對於“字母數字”字串的排序結果是不確定的。舉個例子,假定你有很多圖片名稱存放於數組中:

代碼如下 複製代碼

$arr = array(
0=>'madden2011.png',
1=>'madden2011-1.png',
2=>'madden2011-2.png',
3=>'madden2012.png'
);

你怎樣對這個數組進行排序呢?如果你用sort()對該數組排序,結果是這樣的:

Array
(
[0] => madden2011-1.png
[1] => madden2011-2.png
[2] => madden2011.png
[3] => madden2012.png
)

有時候這就是我們想要的,但是我們想保留原來的下標怎麼辦?解決該問題可以使用natsort()函數,該函數用一種自然的方法對數組排序:

代碼如下 複製代碼

$arr = array(
0=>'madden2011.png',
1=>'madden2011-1.png',
2=>'madden2011-2.png',
3=>'madden2012.png'
);

natsort($arr);
echo "

"; print_r($arr); echo "
";
?>

運行結果:

Array
(
[1] => madden2011-1.png
[2] => madden2011-2.png
[0] => madden2011.png
[3] => madden2012.png
)

遍曆過程中的改值操作
引用操作符&
看下面這段代碼中的$array數組,在foreach迴圈時對$value使用引用操作符,這樣在迴圈中修改$value的值的時候,便將$array中對應的元素值修改了。

代碼如下 複製代碼

$array = array("A"=>1, "B"=>1, "C"=>1, "D"=>1);
foreach($array as &$value)
$value = 2;
print_r($array);
?>

上段代碼的輸出如下:

Array ( [A] => 2 [B] => 2 [C] => 2 [D] => 2 )
可以看到,$array中各個鍵對應的值都被修改成了2。看來這種方法確實奏效。

利用索引值運算元組的元素
有的時候,數組中表示的可能是一些互相關聯的元素,如果遇到了這些相互關聯的元素中的一個,就將其他元素做一個標記的話,上面的引用肯定就不管用了。這時候修改這些關聯元素的時候,就要使用其對應的索引值了。先試試看管用不:

代碼如下 複製代碼

$array = array("A"=>1, "B"=>1, "C"=>1, "D"=>1);
foreach($array as $key => $value){
if($key == "B"){
$array["A"] = "CHANGE";
$array["D"] = "CHANGE";
print_r($array);
echo '
';
}

if($value === "CHANGE")
echo $value.'
';
}
print_r($array);
?>

別著急看輸出,我們想象中的應該是什麼樣呢?列印修改後的數組,列印一個“CHANGE”,再列印一遍修改後的數組。對嗎?來看一下輸出吧!

Array ( [A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE )
Array ( [A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE )
咦?怎麼個情況?我們的CHANGE哪去了?

按照我們的想法,既然$array已經改變了,那麼當遍曆到索引值為“D”的元素時,應當輸出它的新值“CHANGE”才對!可是事實並不是我們想的那樣。PHP在這裡做了什麼手腳呢?把上面的代碼稍微修改一下。既然列印數組的時候,“D”=>CHANGE沒錯,那我們修改第二個if語句的判斷條件:

代碼如下 複製代碼

$array = array("A"=>1, "B"=>1, "C"=>1, "D"=>1);
foreach($array as $key => $value){
if($key == "B"){
$array["A"] = "CHANGE";
$array["D"] = "CHANGE";
print_r($array);
echo '
';
}

if($array[$key] === "CHANGE")
echo $value.'
';
}
print_r($array);
?>

猜猜它會輸出什嗎?$value肯定不會等於“CHANGE”啦!難道等於1嗎?

代碼如下 複製代碼
Array ( [A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE )
1
Array ( [A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE )

那麼,它確實就是1了。

這究竟是神馬原因呢?翻到PHP文檔的foreach那頁,恍然:

Note: 除非數組是被引用,foreach 所操作的是指定數組的一個拷貝,而不是該數組本身。foreach對數組指標有些副作用。除非對其重設,在 foreach 迴圈中或迴圈後都不要依賴數組指標的值。

原來foreach所操作的是指定數組的一個拷貝。怪不得,取$value不管用了呢!理解到這裡,上面的問題就解決了。只要在foreach中,直接按照鍵取$array中的元素進行各種判斷賦值操作就可以了。


總結及延伸
PHP的數組遍曆和操作能力確實非常強大,然而對一些稍複雜問題的解決方案卻不是那麼明顯。其實在任何領域都是這樣,一個語言和文法提供的都是基本的操作,對於複雜的問題的解決辦法都需要開發人員自己的思考、想象力和代碼編寫來完成。

http://www.bkjia.com/PHPjc/631503.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/631503.htmlTechArticle前面我講過簡單的數組遍曆,這些基於foreach,for之類的語句,下面我來介紹數組的進階遍曆方法介紹,各位朋友可參考,這些數組才真用於開...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.