PHPイテレータとジェネレータ: ` ArrayIterator `と` FilterIterator `クラスから始める


PHPを使用するよりも、データ変換および/またはフィルタリングを実行するには、プレーンPHPのオブジェクトの配列をループする他の方法がありますbuilt-in array functions provided by the language .
これらの関数は数多くありますが、要素のリストをループしながら念頭に置いた操作を実現するのに役立つでしょうが、PHPの配列が入力されていないという事実によって制限されます.つまり、ほとんどの場合、コードのロジックを進める前に何らかの種類の型チェックを行う必要があります.これは非常に冗長であり、非常に保守的で読みやすいコードではありません.
読みやすさと効率であなたのforeach オブジェクトのコレクションを越えるループ:イテレータ.
The Iterator interface 与えられたクラスインスタンスの小道具がAのあらゆる段階で繰り返されるとき、カスタムPHPふるまいを定義することができますforeach ループ.
クラスのメソッドによって反復ロジックが実装されるので、クラスのインターフェイスを実装すると、内部イテレータが生成されます.
このインターフェイスを使用する場合、実装する必要があります.
- current() , を返します.
- key() , 現在の反復項目キーを取得する
- next() , を指定します.
- rewind() , 反復を開始する位置を
- valid() , 現在の位置に値があるかどうかを示します
場合によっては、Iterator あまりにもビジネスロジック固有(例えば、ディレクトリ内のファイルを繰り返す)されていない一般的な日々のタスクのインターフェイス自分.この種の一般的なタスクでは、PHPpredefined iterators それはあなたの人生を容易にします.
このポストでは、2つのPHP組み込みイテレータを考えます.
  • the ArrayIterator class
  • the FilterIterator class
  • With ArrayIterator , 配列やオブジェクトを反復処理するときに、値とキーを簡単に設定解除または変更できます
    // we assume that instances 1 to 4 were created earlier
    $myList = new \ArrayIterator();
    $myList->append($instance1);
    $myList->append($instance2);
    $myList->append($instance3);
    $myList->append($instance4);
    
    echo $myList->count(); // gives you the size of your list
    while($myList->valid()) { // you'll recognize here one of the implemented methods from `Iterator` interface
        $instanceItem = $myList->current(); 
        // do something with instance keys/values here
        $myList->next();
    }
    
    これはかなりきちんとしている間.ArrayIterator 他のイテレータと共に使用されるとき、より多くの能力を示しますFilterIterator .
    The FilterIterator 抽象クラスでは、foreach ループは便利に反復の間に条件に基づいて値を取得しますこの条件はaccept このイテレータを拡張するクラスのメソッドhttps://www.php.net/manual/en/class.filteriterator.php ).
    下記の例を参照ください.
    < div >
    これを壊しましょう:
    <ウル>
  • 動的なint変数の倍数である数だけを取得する例のフィルタクラスを作成しますArrayIterator リスト;ここでは、数の単純なリストを使用していますが、もちろん、いくつかの演算を実行する必要がある複雑なオブジェクトの配列を指定できます
  • このフィルタクラスは、PHPFilterIterator
  • それは$_filter 我々がフィルタリングでチェックする変数であるメンバー
  • FilterIterator コンストラクタとその実装accept 必要な方法
  • < ull >
    クラスをハイライト表示する
    class IsMultipleOfFilter extends \FilterIterator {
        private int $_filter;
        public function __construct(\Iterator $iterator, int $filter) {
            parent::__construct($iterator);
            $this->_filter = $filter;
        }
        public function accept(): bool {
            return $this->current() % $this->_filter === 0;
        }
    }
    
    < div >
    <ウル>
  • フィルタの準備ができましたので、フィルタリングしたいリストを作成しましょう.
  • < ull >
    クラスをハイライト表示する
    $myList = new \ArrayIterator();
    $myList->append(1);
    $myList->append(2);
    $myList->append(3);
    $myList->append(4);
    $myList->append(5);
    $myList->append(6);
    $myList->append(7);
    $myList->append(8);
    $myList->append(9);
    $myList->append(10);
    
    < div >
    <ウル>
  • それから、フィルタのインスタンスを作成しましょう.これはフィルタリングされたリストになりますArrayIterator リストとフィルタは偶数の数字だけを得るために、例えば(ナンバー2)=& gt ;
  • < ull >
    クラスをハイライト表示する
    $myFilteredList = new IsMultipleOfFilter($myList, 2);
    
    < div >
    <ウル>
  • フィルタリングされたリスト=& gt ;の要素をエコーすることで、すべてが期待通りに動作することを確認しましょう
  • < ull >
    クラスをハイライト表示する
    foreach ($myFilteredList as $item) {
        echo $item.PHP_EOL;
    }
    
    < div >
    < p >あなたはこの単純なユースケースを理解するだけで、新しい強力な反復オプションを得たこれをより複雑な値を保持するリストに適用することはできますが、原理は同じままです.p >
    イテレータとジェネレータは最初に威嚇することができます.したがって、この例では、これらの構文を使用する際に、より多くの信頼を得ることができます.p >
    私は、これまで、専用のシリーズでより多くの内容を掲示します、そして、それまで、良い休日を持ちますp >