摘要:由于沒有方法,所以就不能用重置游標(biāo),這個(gè)時(shí)候已經(jīng)到最后了,所以為空一種占位符形式的迭代器,不執(zhí)行任何操作。檢查是否含有子節(jié)點(diǎn)輸出所有字節(jié)點(diǎn)將一個(gè)樹形結(jié)構(gòu)的迭代器展開為一維結(jié)構(gòu)。
Iterator界面
本段內(nèi)容來自阮一峰老師再加自己的部分注解
SPL規(guī)定,所有部署了Iterator界面的class,都可以用在foreach Loop中。Iterator界面中包含5個(gè)必須部署的方法:
* current() This method returns the current index"s value. You are solely responsible for tracking what the current index is as the interface does not do this for you. (返回當(dāng)前索引值) * key() This method returns the value of the current index"s key. For foreach loops this is extremely important so that the key value can be populated. (返回當(dāng)前的索引key) * next() This method moves the internal index forward one entry. (迭代中的內(nèi)部指針往前進(jìn)一步) * rewind() This method should reset the internal index to the first element. (重置迭代中的內(nèi)部指針) * valid() This method should return true or false if there is a current element. It is called after rewind() or next(). (驗(yàn)證內(nèi)部指針是否到最后一行)
Example
class ArrayReloaded implements Iterator { /** * 如前一篇文章所說,該類實(shí)現(xiàn)了Iterator接口,所以該類對(duì)象就是ZEND_ITER_OBJECT,對(duì)于ZEND_ITER_OBJECT的類對(duì)象,會(huì)通過調(diào)用對(duì)象實(shí)現(xiàn)的Iterator接口相關(guān)函數(shù)來進(jìn)行foreach。 */ private $array = array(); private $valid = FALSE; function __construct($array) { $this->array = $array; } function rewind(){ /** * reset: 將數(shù)組的內(nèi)部指針指向第一個(gè)單元,如果數(shù)組為空則返回false; * 所以下述語句表示: 數(shù)組不為空并且已重置到第一個(gè)單元; */ $this->valid = (FALSE !== reset($this->array)); } function current(){ return current($this->array); } function key(){ return key($this->array); } function next(){ /** * next: 將數(shù)組中的內(nèi)部指針向前移動(dòng)一位 * 返回?cái)?shù)組內(nèi)部指針指向的下一個(gè)單元的值,或當(dāng)沒有更多單元時(shí)返回 FALSE。 * 所以下述語句表示: 如果還有下一個(gè)單元的話,指針移動(dòng)到下個(gè)單元并返回true; */ $this->valid = (FALSE !== next($this->array)); } function valid(){ return $this->valid; } #↑↑ 以上5個(gè)方法是必須實(shí)現(xiàn)的接口方法,也可以再擴(kuò)展prev和end等方法,后續(xù)會(huì)介紹一些SPL內(nèi)置的實(shí)現(xiàn)了itertor接口的類,這些類可以拿來直接使用 } $arr = array( "color1" => "red", "color2" => "blue", "color3" => "green", "color4" => "plack", "color5" => "purple" ); $colors = new ArrayReloaded($arr); # 通過foreach來遍歷 foreach($colors as $k => $v){ echo $k.":".$v."ArrayIterator
"; } # 通過while來遍歷 /** * 1: foreach的內(nèi)部實(shí)現(xiàn)方式其實(shí)也是如此,事實(shí)上直接用while來遍歷性能更高 * 2: 在使用迭代器來遍歷的時(shí)候,一定要記住要rewind和next,而PHP的foreach遍歷早已把rewind和next給集成了; */ echo "
"; $colors -> rewind(); while($colors -> valid()){ echo $colors -> key().":".$colors -> current()."
"; $colors -> next(); }
ArrayIterator implements ArrayAccess , SeekableIterator , Countable , Serializable
這是一個(gè)非常有用的迭代器,里面實(shí)現(xiàn)了排序,添加,篩選等foreach不能直接實(shí)現(xiàn)的方法(都是要全部遍歷出來再進(jìn)行判斷處理,代碼不優(yōu)雅維護(hù)性差)
Example
"red", "color3" => "green", "color4" => "plack", "color2" => "blue", "color5" => "purple" ); // $colors = new ArrayIterator($arr); //可以直接通過實(shí)例一個(gè)數(shù)組迭代器對(duì)象,然后while這個(gè)迭代器; //但以下的方式要更易于擴(kuò)展 //先實(shí)例一個(gè)array對(duì)象 $colorsObj = new ArrayObject($arr); $it = $colorsObj -> getIterator(); //獲得當(dāng)前的ArrayIterator # 通過while來遍歷 $it -> rewind(); while($it -> valid()){ echo $it -> key().":".$it -> current()."AppendIterator
"; $it -> next(); } #通過iterator迭代器來遍歷就變得很靈活 echo $colorsObj -> count(); //元素?cái)?shù)量統(tǒng)計(jì) //從第三個(gè)開始遍歷 $it -> rewind(); //凡是要使用迭代器之前先重置; if($it -> valid()){ $it -> seek(2); //從0開始的,第二個(gè)位置 while($it -> valid()){ echo $it -> key().":".$it -> current()."
"; $it -> next(); } } //對(duì)索引名進(jìn)行升序排列 $it -> ksort(); foreach($it as $k => $v){ echo $k ."-->". $v."
"; } //對(duì)索引值進(jìn)行排序 $it -> asort(); foreach($it as $k => $v){ echo $k ."-->". $v."
"; } //這些對(duì)象方法是否很熟悉? 這就是上一篇文章中說到的 "SPL是一種使object(物體)模仿array(數(shù)組)行為的interfaces和classes"
按順序迭代訪問幾個(gè)不同的迭代器。例如,希望在一次循環(huán)中迭代訪問兩個(gè)或者更多的組合。這個(gè)迭代器的append方法類似于array_merge()函數(shù)來合并數(shù)組。
Example
$arr1 = array( "color1" => "red", "color3" => "green", "color4" => "plack", "color2" => "blue", "color5" => "purple" ); $arr2 = array( "fruit1" => "apple", "fruit2" => "orange", "fruit3" => "banana", "fruit4" => "grape", "fruit5" => "strawberry", ); $ao1 = new ArrayIterator($arr1); $ao2 = new ArrayIterator($arr2); $iterator = new AppendIterator(); $iterator -> append($ao1); $iterator -> append($ao2); foreach($iterator as $k => $v){ echo $k.":".$v,"MultipleIterator
"; }
迭代器的鏈接器,更多參考連接 http://php.net/manual/en/clas...
$person_id = new ArrayIterator(array("001", "002", "003")); $person_name = new ArrayIterator(array("張三", "李四", "王五")); $person_age = new ArrayIterator(array(22, 23, 11)); $mit = new MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC); $mit->attachIterator($person_id, "ID"); $mit->attachIterator($person_name, "NAME"); $mit->attachIterator($person_age, "AGE"); echo"連接的迭代器個(gè)數(shù):".$mit->countIterators() . " "; //3 foreach ($mit as $person) { print_r($person); } /**output Array ( [ID] => 001 [NAME] => 張三 [AGE] => 22 ) Array ( [ID] => 002 [NAME] => 李四 [AGE] => 23 ) Array ( [ID] => 003 [NAME] => 王五 [AGE] => 11 ) **/LimitIterator
返回給定數(shù)量的結(jié)果以及從集合中取出結(jié)果的起始索引點(diǎn)
FilterIterator基于OuterIterator接口,用于過濾數(shù)據(jù),返回符合條件的元素。必須實(shí)現(xiàn)一個(gè)抽象方法accept(),此方法必須為迭代器的當(dāng)前項(xiàng)返回true或false
class UserFilter extends FilterIterator{ private $userFilter; public function __construct(Iterator $iterator , $filter){ parent::__construct($iterator); //要過濾的參數(shù) $this->userFilter = $filter; } public function accept(){ /* * getInnerIterator(): 獲得內(nèi)部的迭代器 * current(): 然后獲取當(dāng)前的元素 * in strcmp(string str1,string str2) 區(qū)分字符串中字母大小寫地比較,返回0就相同 * int strcasecmp(string str1,string str2) 忽略字符串中字母大小寫地比較,返回0就相同 * 如果accept返回false的話就過濾掉 */ $user = $this->getInnerIterator()->current(); if (strcasecmp($user["name"] , $this->userFilter) == 0) { return false; } return true; } } $array = array (array ("name" => "Jonathan" , "id" => "5") , array ("name" => "Abdul" , "id" => "22"),array ("name" => "zhouzhou" , "id" => "9")); $object = new ArrayObject($array); //去除掉名為abdul的人員 $iterator = new UserFilter($object->getIterator() , "abdul"); foreach ($iterator as $result) { echo $result["name"]; } /**output * Jonathan **/RegexIterator繼承FilterIterator,支持使用正則表達(dá)式模式匹配和修改迭代器中的元素。經(jīng)常用于將字符串匹配。
更多參考: http://cn2.php.net/manual/zh/...//可以實(shí)現(xiàn): preg_match_all(), preg_match(), preg_replace(),preg_split()等函數(shù)的功能 $a = new ArrayIterator(array("test1", "test2", "test3")); $i = new RegexIterator($a, "/^(test)(d+)/", RegexIterator::REPLACE); $i->replacement = "$2:$1"; print_r(iterator_to_array($i)); /**output Array ( [0] => 1:test [1] => 2:test [2] => 3:test ) **/IteratorIterator一種通用類型的迭代器,所有實(shí)現(xiàn)了Traversable接口的類都可以被它迭代訪問。
CachingIterator用來執(zhí)行提前讀取一個(gè)元素的迭代操作,例如可以用于確定當(dāng)前元素是否為最后一個(gè)元素。
$array = array ("koala" , "kangaroo" , "wombat" , "wallaby" , "emu" , "kiwi" , "kookaburra" , "platypus"); $object = new CachingIterator(new ArrayIterator($array)); foreach ($object as $value) { echo $value; if ($object->hasNext()) { echo ","; //如果有下一項(xiàng)的話才輸出 突出不了該迭代器的作用啊,其他迭代器也可以搞定的 } } /**output * koala,kangaroo,wombat,wallaby,emu,kiwi,kookaburra,platypus **/SeekableIterator用于創(chuàng)建非順序訪問的迭代器,允許跳轉(zhuǎn)到迭代器中的任何一點(diǎn)上。
$array = array("apple", "banana", "cherry", "damson", "elderberry"); $iterator = new ArrayIterator($array); $iterator->seek(3); //起始0從第3個(gè)開始取; echo $iterator->current()."NoRewindIterator
"; /**output damson **/用于不能多次迭代的集合,適用于在迭代過程中執(zhí)行一次性操作。
$fruit = array("apple", "banana", "cranberry"); $arr = new ArrayObject($fruit); $it = new NoRewindIterator($arr->getIterator()); echo "Fruit A: "; foreach ($it as $item) { echo $item . " "; } echo "Fruit B: "; // ↓↓ 由于NoRewindIterator沒有rewind方法,所以foreach就不能用rewind重置游標(biāo),這個(gè)時(shí)候$it已經(jīng)到最后了,所以為空; foreach ($it as $item) { echo $item . " "; } /**output Fruit A: apple banana cranberry Fruit B: **/EmptyIterator一種占位符形式的迭代器,不執(zhí)行任何操作。當(dāng)要實(shí)現(xiàn)某個(gè)抽象類的方法并且這個(gè)方法需要返回一個(gè)迭代器時(shí),可以使用這種迭代器。
InfiniteIterator用于持續(xù)地訪問數(shù)據(jù),當(dāng)?shù)阶詈笠粋€(gè)元素時(shí),會(huì)再次從第一個(gè)元素開始迭代訪問。
$arrayit = new ArrayIterator(array("cat", "dog")); $infinite = new InfiniteIterator($arrayit); //必須限制否則就是死循環(huán) $limit = new LimitIterator($infinite, 0, 7); foreach ($limit as $value) { echo "$value "; }RecursiveArrayIterator創(chuàng)建一個(gè)用于遞歸形式數(shù)組結(jié)構(gòu)的迭代器,類似于多維數(shù)組.它為許多更復(fù)雜的迭代器提供了所需的操作,如RecursiveTreeIterator和RecursiveIteratorIterator迭代器。
$fruits = array("a" => "lemon", "b" => "orange", array("a" => "apple", "p" => "pear")); $iterator = new RecursiveArrayIterator($fruits); while ($iterator->valid()) { //檢查是否含有子節(jié)點(diǎn) if ($iterator->hasChildren()) { //輸出所有字節(jié)點(diǎn) foreach ($iterator->getChildren() as $key => $value) { echo $key . " : " . $value . " "; } } else { echo "No children. "; } $iterator->next(); } /**output No children. No children. a : apple p : pear **/RecursiveIteratorIterator將一個(gè)樹形結(jié)構(gòu)的迭代器展開為一維結(jié)構(gòu)。
$fruits = array("a" => "lemon", "b" => "orange", array("a" => "apple", "p" => "pear","c" => ["a","b"])); $arrayiter = new RecursiveArrayIterator($fruits); $iteriter = new RecursiveIteratorIterator($arrayiter); foreach ($iteriter as $key => $value) { $d = $iteriter->getDepth(); echo "depth=$d k=$key v=$value "; } /**output depth=0 k=a v=lemon depth=0 k=b v=orange depth=1 k=a v=apple depth=1 k=p v=pear depth=2 k=0 v=a depth=2 k=1 v=b **/RecursiveTreeIterator以可視在方式顯示一個(gè)樹形結(jié)構(gòu)。
$hey = array("a" => "lemon", "b" => "orange", array("a" => "apple", "p" => "pear")); $awesome = new RecursiveTreeIterator( new RecursiveArrayIterator($hey), null, null, RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($awesome as $line) echo $line . PHP_EOL; /**output |-lemon |-orange |-apple -pear **/ParentIterator是一個(gè)擴(kuò)展的FilterIterator迭代器,它可以過濾掉來自于RecursiveIterator迭代器的非父元素,只找出子節(jié)點(diǎn)的鍵值。通俗來說,就是去枝留葉。
$hey = array ("a" => "lemon" , "b" => "orange" , array ("a" => "apple" , "p" => "pear")); $arrayIterator = new RecursiveArrayIterator($hey); $it = new ParentIterator($arrayIterator); print_r(iterator_to_array($it)); /**output * Array * ( * [0] => Array * ( * [a] => apple * [p] => pear * ) * ) **/RecursiveFilterIterator是FilterIterator迭代器的遞歸形式,也要求實(shí)現(xiàn)抽象的accept()方法,但在這個(gè)方法中應(yīng)該使用$this->getInnerIterator()方法訪問當(dāng)前正在迭代的迭代器。
class TestsOnlyFilter extends RecursiveFilterIterator{ public function accept(){ // 找出含有“葉”的元素 return $this->hasChildren() || (mb_strpos($this->current() , "葉") !== false); } } $array = array ("葉1" , array ("力2" , "葉3" , "葉4") , "葉5"); $iterator = new RecursiveArrayIterator($array); $filter = new TestsOnlyFilter($iterator); $filter = new RecursiveIteratorIterator($filter); print_r(iterator_to_array($filter)); /**output * Array * ( * [0] => 葉1 * [1] => 葉3 //只會(huì)找出含葉的元素,不會(huì)把元素成員全部顯示出來 * [2] => 葉5 * ) **/RecursiveRegexIterator是RegexIterator迭代器的遞歸形式,只接受RecursiveIterator迭代器作為迭代對(duì)象。
$rArrayIterator = new RecursiveArrayIterator(array ("葉1" , array ("tet3" , "葉4" , "葉5"))); $rRegexIterator = new RecursiveRegexIterator( $rArrayIterator , "/^葉/" , RecursiveRegexIterator::ALL_MATCHES ); foreach ($rRegexIterator as $key1 => $value1) { if ($rRegexIterator->hasChildren()) { // print all children echo "Children: "; foreach ($rRegexIterator->getChildren() as $key => $value) { echo $value . " "; } echo " "; } else { echo "No children "; } } /**output * No children * Children: 葉4 葉5 **/RecursiveCachingIterator在RecursiveIterator迭代器上執(zhí)行提前讀取一個(gè)元素的遞歸操作。
CallbackFilterIterator(PHP5.4)同時(shí)執(zhí)行過濾和回調(diào)操作,在找到一個(gè)匹配的元素之后會(huì)調(diào)用回調(diào)函數(shù)。
$hey = array ("李1" , "葉2" , "葉3" , "葉4" , "葉5" , "葉6" ,); $arrayIterator = new RecursiveArrayIterator($hey); $isYe = function($current){ return mb_strpos($current , "葉") !== false; }; $rs = new CallbackFilterIterator($arrayIterator , $isYe); print_r(iterator_to_array($rs)); /**output * Array * ( * [0] => 葉2 * [1] => 葉3 * [2] => 葉4 * [3] => 葉5 * [4] => 葉6 * ) **/RecursiveCallbackFilterIterator(PHP5.4)在RecursiveIterator迭代器上進(jìn)行遞歸操作,同時(shí)執(zhí)行過濾和回調(diào)操作,在找到一個(gè)匹配的元素之后會(huì)調(diào)用回調(diào)函數(shù)。
function doesntStartWithLetterT($current){ $rs = $current->getFileName(); return $rs[0] !== "T"; } $rdi = new RecursiveDirectoryIterator(__DIR__); $files = new RecursiveCallbackFilterIterator($rdi , "doesntStartWithLetterT"); foreach (new RecursiveIteratorIterator($files) as $file) { echo $file->getPathname() . PHP_EOL; }DirectoryIterator目錄文件遍歷器,提供了查詢當(dāng)前文件的所有信息的方法(是否可讀可寫,所屬,權(quán)限等等),具體參考 http://cn2.php.net/manual/zh/...
$it = new DirectoryIterator("../"); foreach ($it as $file) { //用isDot ()方法分別過濾掉“.”和“..”目錄 if (!$it->isDot()) { echo $file . " "; } }RecursiveDirectoryIterator遞歸目錄文件遍歷器,可實(shí)現(xiàn)列出所有目錄層次結(jié)構(gòu),而不是只操作一個(gè)目錄。具體看:http://cn2.php.net/manual/zh/...
//列出指定目錄中所有文件 $path = realpath("../"); $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path) , RecursiveIteratorIterator::SELF_FIRST); foreach ($objects as $name => $object) { echo "$name "; }FilesystemIterator是DirectoryIterator的遍歷器
$it = new FilesystemIterator("../"); foreach ($it as $fileinfo) { echo $fileinfo->getFilename() . " "; }GlobIterator帶匹配模式的文件遍歷器
$iterator = new GlobIterator("*.php"); if (!$iterator->count()) { echo "無php文件"; } else { $n = 0; printf("總計(jì) %d 個(gè)php文件 " , $iterator->count()); foreach ($iterator as $item) { printf("[%d] %s " , ++ $n , $iterator->key()); } }SimpleXMLIteratorXMl文檔訪問迭代器,可實(shí)現(xiàn)訪問xml中所有節(jié)點(diǎn)
$xml = <<參考鏈接:PHP Basics Jim Smith XML basics XML; // SimpleXML轉(zhuǎn)換為數(shù)組 function sxiToArray($sxi){ $a = array (); for ($sxi->rewind();$sxi->valid();$sxi->next()) { if (!array_key_exists($sxi->key() , $a)) { $a[$sxi->key()] = array (); } if ($sxi->hasChildren()) { $a[$sxi->key()][] = sxiToArray($sxi->current()); } else { $a[$sxi->key()][] = strval($sxi->current()); } } return $a; } $xmlIterator = new SimpleXMLIterator($xml); $rs = sxiToArray($xmlIterator); print_r($rs); /**output * Array * ( * [book] => Array * ( * [0] => Array * ( * [title] => Array * ( * [0] => PHP Basics * ) * [author] => Array * ( * [0] => Jim Smith * ) * ) * [1] => XML basics * ) * ) **/http://www.ruanyifeng.com/blo...
http://www.cnblogs.com/Script...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/31490.html
摘要:什么是是標(biāo)準(zhǔn)庫的縮寫。根據(jù)官方定義,它是是用于解決典型問題的一組接口與類的集合。而的對(duì)象則嚴(yán)格以堆棧的形式描述數(shù)據(jù),并提供對(duì)應(yīng)的方法。返回所有已注冊(cè)的函數(shù)。 什么是SPL SPL是Standard PHP Library(PHP標(biāo)準(zhǔn)庫)的縮寫。 根據(jù)官方定義,它是a collection of interfaces and classes that are meant to solve...
摘要:簡(jiǎn)述雙鏈表是一種重要的線性存儲(chǔ)結(jié)構(gòu),對(duì)于雙鏈表中的每個(gè)節(jié)點(diǎn),不僅僅存儲(chǔ)自己的信息,還要保存前驅(qū)和后繼節(jié)點(diǎn)的地址。 簡(jiǎn)述 雙鏈表是一種重要的線性存儲(chǔ)結(jié)構(gòu),對(duì)于雙鏈表中的每個(gè)節(jié)點(diǎn),不僅僅存儲(chǔ)自己的信息,還要保存前驅(qū)和后繼節(jié)點(diǎn)的地址。 showImg(https://segmentfault.com/img/remote/1460000019231932?w=813&h=236); 類摘要 ...
摘要:是用來存儲(chǔ)一組對(duì)象的,特別是當(dāng)你需要唯一標(biāo)識(shí)對(duì)象的時(shí)候。類實(shí)現(xiàn)了四個(gè)接口。可實(shí)現(xiàn)統(tǒng)計(jì)迭代序列化數(shù)組式訪問等功能。 PHP SPL SplObjectStorage是用來存儲(chǔ)一組對(duì)象的,特別是當(dāng)你需要唯一標(biāo)識(shí)對(duì)象的時(shí)候。PHP SPL SplObjectStorage類實(shí)現(xiàn)了Countable,Iterator,Serializable,ArrayAccess四個(gè)接口。可實(shí)現(xiàn)統(tǒng)計(jì)、迭代、...
摘要:我把分為五個(gè)部分,,,,而其中是就是做一些類的介紹與相關(guān)的類在各自文章內(nèi),在介紹這些類之前,先介紹幾個(gè)接口數(shù)組式訪問接口只要實(shí)現(xiàn)了這個(gè)接口,就可以使得像那樣操作。只有內(nèi)部的類用寫的類才可以直接實(shí)現(xiàn)接口代碼中使用或接口來實(shí)現(xiàn)遍歷。 我把SPL分為五個(gè)部分:Iterator,Classes,Exceptions,Datastructures,F(xiàn)unction;而其中classes是就是做一...
摘要:這兩個(gè)類都是繼承自,分別派生自的堆棧模式和隊(duì)列模式所以放在一起來介紹堆棧類摘要方法重寫了父類,固定為堆棧模式,然后此處只需要傳或者。 這兩個(gè)類都是繼承自SplDoublyLinkedList,分別派生自SplDoublyLinkedList的堆棧模式和隊(duì)列模式;所以放在一起來介紹; 堆棧SplStack showImg(https://segmentfault.com/img/remo...
閱讀 1408·2023-04-26 01:58
閱讀 2282·2021-11-04 16:04
閱讀 1753·2021-08-31 09:42
閱讀 1765·2021-07-25 21:37
閱讀 1066·2019-08-30 15:54
閱讀 2074·2019-08-30 15:53
閱讀 3047·2019-08-29 13:28
閱讀 2687·2019-08-29 10:56