PHP Iterator 100 本ノック FilterIterator
その名の通り,Iterator を Filter する.
abstract クラスなので,継承前提.
code:php
<?php
class EvenFilterIterator extends FilterIterator
{
public function accept(): bool
{
// 偶数なら OK
return ($this->current() % 2) === 0;
}
}
$iter = new ArrayIterator($items);
$filtered = new EvenFilterIterator($iter);
foreach($filtered as $item) {
echo "$item\n";
}
この結果は
2
4
6
8
内部イテレータを反復処理し,accept()が true だったときの要素を残すって感じだと思う.
accept() 内で現在の要素を絶対使わないといけないわけじゃないので,常に true を返せば全部残る,そんなかんじ.
$this->current()を使えば現在の要素が取れるので,基本的にはこいつを呼ぶ感じになる.
array_filter() みたいなことをしたいなら
code:php
<?php
class FunctionalFilterIterator extends FilterIterator
{
public function __construct(Iterator $iterator, private ?Closure $callback = null){
parent::__construct($iterator);
}
public function accept(): bool
{
$c = $this->current();
return $this->callback === null ? isset($c) : ($this->callback)($c);
}
}
こうしておけば
code:php
var_dump(
iterator_to_array(
new FunctionalFilterIterator(
),
),
);
これの結果は
array(5) {
int(0)
int(1)
int(2)
int(3)
int(5)
}
code:php
var_dump(
iterator_to_array(
new FunctionalFilterIterator(
fn (int|null $item) => $item !== null && ($item%2) === 0,
),
),
);
これの結果は
array(2) {
int(0)
int(2)
}
という感じになる