成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【SPL標(biāo)準(zhǔn)庫專題(2)】Iterator

focusj / 2449人閱讀

摘要:由于沒有方法,所以就不能用重置游標(biāo),這個時候已經(jīng)到最后了,所以為空一種占位符形式的迭代器,不執(zhí)行任何操作。檢查是否含有子節(jié)點輸出所有字節(jié)點將一個樹形結(jié)構(gòu)的迭代器展開為一維結(jié)構(gòu)。

Iterator界面
本段內(nèi)容來自阮一峰老師再加自己的部分注解

SPL規(guī)定,所有部署了Iterator界面的class,都可以用在foreach Loop中。Iterator界面中包含5個必須部署的方法:

* 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(). (驗證內(nèi)部指針是否到最后一行)

Example

class ArrayReloaded implements Iterator {
  /**
   * 如前一篇文章所說,該類實現(xiàn)了Iterator接口,所以該類對象就是ZEND_ITER_OBJECT,對于ZEND_ITER_OBJECT的類對象,會通過調(diào)用對象實現(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)部指針指向第一個單元,如果數(shù)組為空則返回false;
     *  所以下述語句表示: 數(shù)組不為空并且已重置到第一個單元;
     */
    $this->valid = (FALSE !== reset($this->array));
  }

  function current(){
    return current($this->array);
  }

  function key(){
    return key($this->array);
  }

  function next(){
    /**
     * next: 將數(shù)組中的內(nèi)部指針向前移動一位
     * 返回數(shù)組內(nèi)部指針指向的下一個單元的值,或當(dāng)沒有更多單元時返回 FALSE。
     * 所以下述語句表示: 如果還有下一個單元的話,指針移動到下個單元并返回true;
     */
    $this->valid = (FALSE !== next($this->array));
  }

  function valid(){
    return $this->valid;
  }

  #↑↑ 以上5個方法是必須實現(xiàn)的接口方法,也可以再擴展prev和end等方法,后續(xù)會介紹一些SPL內(nèi)置的實現(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."
"; } # 通過while來遍歷 /** * 1: foreach的內(nèi)部實現(xiàn)方式其實也是如此,事實上直接用while來遍歷性能更高 * 2: 在使用迭代器來遍歷的時候,一定要記住要rewind和next,而PHP的foreach遍歷早已把rewind和next給集成了; */ echo "
"; $colors -> rewind(); while($colors -> valid()){ echo $colors -> key().":".$colors -> current()."
"; $colors -> next(); }
ArrayIterator
ArrayIterator implements ArrayAccess , SeekableIterator , Countable , Serializable

這是一個非常有用的迭代器,里面實現(xiàn)了排序,添加,篩選等foreach不能直接實現(xiàn)的方法(都是要全部遍歷出來再進(jìn)行判斷處理,代碼不優(yōu)雅維護性差)

Example

 "red",
  "color3" => "green",
  "color4" => "plack",
  "color2" => "blue",
  "color5" => "purple"
);

// $colors = new ArrayIterator($arr); //可以直接通過實例一個數(shù)組迭代器對象,然后while這個迭代器;

//但以下的方式要更易于擴展
//先實例一個array對象
$colorsObj = new ArrayObject($arr);
$it = $colorsObj -> getIterator(); //獲得當(dāng)前的ArrayIterator

# 通過while來遍歷
$it -> rewind();
while($it -> valid()){
  echo $it -> key().":".$it -> current()."
"; $it -> next(); } #通過iterator迭代器來遍歷就變得很靈活 echo $colorsObj -> count(); //元素數(shù)量統(tǒng)計 //從第三個開始遍歷 $it -> rewind(); //凡是要使用迭代器之前先重置; if($it -> valid()){ $it -> seek(2); //從0開始的,第二個位置 while($it -> valid()){ echo $it -> key().":".$it -> current()."
"; $it -> next(); } } //對索引名進(jìn)行升序排列 $it -> ksort(); foreach($it as $k => $v){ echo $k ."-->". $v."
"; } //對索引值進(jìn)行排序 $it -> asort(); foreach($it as $k => $v){ echo $k ."-->". $v."
"; } //這些對象方法是否很熟悉? 這就是上一篇文章中說到的 "SPL是一種使object(物體)模仿array(數(shù)組)行為的interfaces和classes"
AppendIterator

按順序迭代訪問幾個不同的迭代器。例如,希望在一次循環(huán)中迭代訪問兩個或者更多的組合。這個迭代器的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"連接的迭代器個數(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é)果的起始索引點


FilterIterator

基于OuterIterator接口,用于過濾數(shù)據(jù),返回符合條件的元素。必須實現(xiàn)一個抽象方法accept(),此方法必須為迭代器的當(dā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/...

//可以實現(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

一種通用類型的迭代器,所有實現(xiàn)了Traversable接口的類都可以被它迭代訪問。

CachingIterator

用來執(zhí)行提前讀取一個元素的迭代操作,例如可以用于確定當(dāng)前元素是否為最后一個元素。

$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 ","; //如果有下一項的話才輸出 突出不了該迭代器的作用啊,其他迭代器也可以搞定的
  }
}
/**output
 * koala,kangaroo,wombat,wallaby,emu,kiwi,kookaburra,platypus
 **/
SeekableIterator

用于創(chuàng)建非順序訪問的迭代器,允許跳轉(zhuǎn)到迭代器中的任何一點上。

$array = array("apple", "banana", "cherry", "damson", "elderberry");
$iterator = new ArrayIterator($array);
$iterator->seek(3); //起始0從第3個開始?。?echo $iterator->current()."
"; /**output damson **/
NoRewindIterator

用于不能多次迭代的集合,適用于在迭代過程中執(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),這個時候$it已經(jīng)到最后了,所以為空;
foreach ($it as $item) {
  echo $item . "
";
}

/**output
Fruit A:
apple
banana
cranberry
Fruit B:
 **/
EmptyIterator

一種占位符形式的迭代器,不執(zhí)行任何操作。當(dāng)要實現(xiàn)某個抽象類的方法并且這個方法需要返回一個迭代器時,可以使用這種迭代器。

InfiniteIterator

用于持續(xù)地訪問數(shù)據(jù),當(dāng)?shù)阶詈笠粋€元素時,會再次從第一個元素開始迭代訪問。

$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)建一個用于遞歸形式數(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é)點
  if ($iterator->hasChildren()) {
    //輸出所有字節(jié)點
    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

將一個樹形結(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

以可視在方式顯示一個樹形結(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

是一個擴展的FilterIterator迭代器,它可以過濾掉來自于RecursiveIterator迭代器的非父元素,只找出子節(jié)點的鍵值。通俗來說,就是去枝留葉。

$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迭代器的遞歸形式,也要求實現(xiàn)抽象的accept()方法,但在這個方法中應(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 //只會找出含葉的元素,不會把元素成員全部顯示出來
 * [2] => 葉5
 * )
 **/
RecursiveRegexIterator

是RegexIterator迭代器的遞歸形式,只接受RecursiveIterator迭代器作為迭代對象。

$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í)行提前讀取一個元素的遞歸操作。

CallbackFilterIterator(PHP5.4)

同時執(zhí)行過濾和回調(diào)操作,在找到一個匹配的元素之后會調(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)行遞歸操作,同時執(zhí)行過濾和回調(diào)操作,在找到一個匹配的元素之后會調(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

遞歸目錄文件遍歷器,可實現(xiàn)列出所有目錄層次結(jié)構(gòu),而不是只操作一個目錄。具體看: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("總計 %d 個php文件
" , $iterator->count());
  foreach ($iterator as $item) {
    printf("[%d] %s
" , ++ $n , $iterator->key());
  }
}
SimpleXMLIterator

XMl文檔訪問迭代器,可實現(xiàn)訪問xml中所有節(jié)點

$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)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/31490.html

相關(guān)文章

  • SPL標(biāo)準(zhǔn)專題(1)】SPL簡介

    摘要:什么是是標(biāo)準(zhǔn)庫的縮寫。根據(jù)官方定義,它是是用于解決典型問題的一組接口與類的集合。而的對象則嚴(yán)格以堆棧的形式描述數(shù)據(jù),并提供對應(yīng)的方法。返回所有已注冊的函數(shù)。 什么是SPL SPL是Standard PHP Library(PHP標(biāo)準(zhǔn)庫)的縮寫。 根據(jù)官方定義,它是a collection of interfaces and classes that are meant to solve...

    GeekGhc 評論0 收藏0
  • SPL標(biāo)準(zhǔn)專題(5)】Datastructures:SplDoublyLinkedList

    摘要:簡述雙鏈表是一種重要的線性存儲結(jié)構(gòu),對于雙鏈表中的每個節(jié)點,不僅僅存儲自己的信息,還要保存前驅(qū)和后繼節(jié)點的地址。 簡述 雙鏈表是一種重要的線性存儲結(jié)構(gòu),對于雙鏈表中的每個節(jié)點,不僅僅存儲自己的信息,還要保存前驅(qū)和后繼節(jié)點的地址。 showImg(https://segmentfault.com/img/remote/1460000019231932?w=813&h=236); 類摘要 ...

    luckyw 評論0 收藏0
  • SPL標(biāo)準(zhǔn)專題(10)】Datastructures:SplObjectStorage

    摘要:是用來存儲一組對象的,特別是當(dāng)你需要唯一標(biāo)識對象的時候。類實現(xiàn)了四個接口??蓪崿F(xiàn)統(tǒng)計迭代序列化數(shù)組式訪問等功能。 PHP SPL SplObjectStorage是用來存儲一組對象的,特別是當(dāng)你需要唯一標(biāo)識對象的時候。PHP SPL SplObjectStorage類實現(xiàn)了Countable,Iterator,Serializable,ArrayAccess四個接口??蓪崿F(xiàn)統(tǒng)計、迭代、...

    ConardLi 評論0 收藏0
  • SPL標(biāo)準(zhǔn)專題(3)】Classes

    摘要:我把分為五個部分,,,,而其中是就是做一些類的介紹與相關(guān)的類在各自文章內(nèi),在介紹這些類之前,先介紹幾個接口數(shù)組式訪問接口只要實現(xiàn)了這個接口,就可以使得像那樣操作。只有內(nèi)部的類用寫的類才可以直接實現(xiàn)接口代碼中使用或接口來實現(xiàn)遍歷。 我把SPL分為五個部分:Iterator,Classes,Exceptions,Datastructures,F(xiàn)unction;而其中classes是就是做一...

    binaryTree 評論0 收藏0
  • SPL標(biāo)準(zhǔn)專題(6)】Datastructures:SplStack & SplQueu

    摘要:這兩個類都是繼承自,分別派生自的堆棧模式和隊列模式所以放在一起來介紹堆棧類摘要方法重寫了父類,固定為堆棧模式,然后此處只需要傳或者。 這兩個類都是繼承自SplDoublyLinkedList,分別派生自SplDoublyLinkedList的堆棧模式和隊列模式;所以放在一起來介紹; 堆棧SplStack showImg(https://segmentfault.com/img/remo...

    TigerChain 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<