RecursiveIteratorIterator
はどのように機能しますか?
PHPマニュアルには、ドキュメントや説明があまりありません。IteratorIterator
とRecursiveIteratorIterator
の違いは何ですか?]
IteratorIterator
とRecursiveIteratorIterator
の違いは何ですか?
これら2つのイテレータの違いを理解するには、まず、使用される命名規則と「再帰」イテレータの意味について少し理解する必要があります。
PHPには、ArrayIterator
やFilesystemIterator
などの非「再帰」イテレーターがあります。 RecursiveArrayIterator
やRecursiveDirectoryIterator
などの「再帰的な」反復子もあります。後者にはドリルダウンできるメソッドがありますが、前者にはありません。
これらのイテレータのインスタンスが、再帰的なものであってもそれ自体でループされる場合、ネストされた配列またはサブディレクトリを持つディレクトリをループしても、値は「トップ」レベルからのみ取得されます。
再帰イテレーターimplement再帰動作(hasChildren()
、getChildren()
を介して)でなくexploitそれ。
再帰イテレータを「再帰可能な」イテレータと考える方が良いかもしれません。それらはabilityを再帰的に繰り返しますが、単に1つのインスタンスを反復処理するだけです。これらのクラスのうち、それは行いません。再帰的な動作を活用するには、読み続けてください。
ここで、RecursiveIteratorIterator
が再生されます。通常のフラットなループで構造にドリルダウンするような方法で、「再帰」イテレーターを呼び出す方法に関する知識があります。再帰的な動作を実行します。基本的に、反復子内の各値をステップオーバーし、再帰するかどうかを確認する「子」があるかどうかを確認し、それらの子のコレクションに出入りする作業を行います。 RecursiveIteratorIterator
のインスタンスをforeachに貼り付け、it構造に潜り込む必要がないようにします。
RecursiveIteratorIterator
が使用されなかった場合、「再帰的」イテレーターのhasChildren()
をチェックし、getChildren()
を使用して、再帰的動作を活用する独自の再帰ループを作成する必要があります。 。
これがRecursiveIteratorIterator
のbriefの概要ですが、IteratorIterator
とはどう違いますか?さて、あなたは基本的にと同じ種類の質問をしていますが、子猫と木との違いは何ですか?両方が同じ百科事典に登場するからです(または反復子の場合は手動)は、2つを混同する必要があるという意味ではありません。
IteratorIterator
の仕事は、任意のTraversable
オブジェクトを取得し、Iterator
インターフェイスを満たすようにラップすることです。これを使用すると、非反復オブジェクトに反復子固有の動作を適用できるようになります。
実用的な例を挙げると、DatePeriod
クラスはTraversable
ですが、Iterator
ではありません。そのため、foreach()
を使用してその値をループできますが、フィルタリングなど、通常イテレーターで行うことはできません。
[〜#〜] task [〜#〜]:次の4週間の月曜日、水曜日、金曜日をループします。
はい、これはforeach
をDatePeriod
- ingし、ループ内でif()
を使用することで簡単です。しかし、それはこの例のポイントではありません!
$period = new DatePeriod(new DateTime, new DateInterval('P1D'), 28);
$dates = new CallbackFilterIterator($period, function ($date) {
return in_array($date->format('l'), array('Monday', 'Wednesday', 'Friday'));
});
foreach ($dates as $date) { … }
CallbackFilterIterator
はIterator
インターフェイスを実装するクラスのインスタンスを予期するため、上記のスニペットは機能しませんが、DatePeriod
はそうしません。ただし、それはTraversable
なので、IteratorIterator
を使用することで簡単にその要件を満たすことができます。
$period = new IteratorIterator(new DatePeriod(…));
ご覧のとおり、これにはnothingイテレータクラスの繰り返しや再帰に関係なく、IteratorIterator
とRecursiveIteratorIterator
。
RecursiveIteraratorIterator
はRecursiveIterator
(「再帰的」イテレーター)を反復処理するためのもので、利用可能な再帰的動作を活用します。
IteratorIterator
は、Iterator
動作を非反復子、Traversable
オブジェクトに適用するためのものです。
RecursiveDirectoryIteratorは、ファイル名だけでなく、パス名全体を表示します。残りはよさそうだ。これは、ファイル名がSplFileInfoによって生成されるためです。代わりにベース名として表示する必要があります。望ましい出力は次のとおりです。
$path =__DIR__;
$dir = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($dir,RecursiveIteratorIterator::SELF_FIRST);
while ($files->valid()) {
$file = $files->current();
$filename = $file->getFilename();
$deep = $files->getDepth();
$indent = str_repeat('│ ', $deep);
$files->next();
$valid = $files->valid();
if ($valid and ($files->getDepth() - 1 == $deep or $files->getDepth() == $deep)) {
echo $indent, "├ $filename\n";
} else {
echo $indent, "└ $filename\n";
}
}
出力:
tree
├ dirA
│ ├ dirB
│ │ └ fileD
│ ├ fileB
│ └ fileC
└ fileA