iterator_apply

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

iterator_applyユーザー関数をイテレータのすべての要素でコールする

説明

iterator_apply(Traversable $iterator, callable $callback, ?array $args = null): int

イテレータ内のすべての要素に対して関数をコールします。

パラメータ

iterator

順次処理したいイテレータオブジェクト

callback

すべての要素に対してコールしたいコールバック関数。 この関数は args のみを受け取ります。 デフォルトでは引数を渡されません。 たとえば count($args) === 3 の場合、 コールバック関数は3変数関数です。

注意: iterator での処理を続けるために、 この関数は true を返さなければなりません。

args

コールバック関数に渡す引数。 引数の arrayargs の個々の要素が コールバック callback に別々の引数として渡されます。

戻り値

イテレータの要素数を返します。

例1 iterator_apply() の例

<?php
function print_caps(Iterator $iterator) {
echo
strtoupper($iterator->current()) . "\n";
return
TRUE;
}

$it = new ArrayIterator(array("Apples", "Bananas", "Cherries"));
iterator_apply($it, "print_caps", array($it));
?>

上の例の出力は以下となります。

APPLES
BANANAS
CHERRIES

参考

  • array_walk() - 配列の全ての要素にユーザー定義の関数を適用する

add a note

User Contributed Notes 2 notes

up
2
tezcatl at fedoraproject dot org
7 years ago
Each of the arguments required by the function, must be in the array supplied in the third argument to iterator_apply. You can use references too. Example:<?phpfunction translate_to(string $target_language, Iterator $words, array $dictionaries) {        $language = ucfirst($target_language);    $dictionary = $dictionaries[$target_language] ?? 'not found';        if ($dictionary === 'not found') {        echo "Not found dictionary for {$language}\n";        return;    }        echo "English words translated to {$language}\n";        $not_found = [];        iterator_apply($words, function($words, $dictionary, &$not_found){            $english_word = $words->current();            $translated_word = $dictionary[$english_word] ?? '';            if ($translated_word !== '') {            echo "{$english_word} translates to {$translated_word}\n";        } else {            $not_found[] = $english_word;        }        return true;        }, array($words, $dictionary, &$not_found));        echo "\nNot found words:\n" . implode("\n", $not_found) . "\n";}$dictionaries = [    'nahuatl' => [        'one' => 'Ze',        'two' => 'Ome',        'three' => 'Yei',        'four' => 'Nahui',    ],];$iterator = new \ArrayIterator(array('one', 'two', 'three', 'four', 'gasoil'));translate_to('nahuatl', $iterator, $dictionaries);?>English words translated to Nahuatlone translates to Zetwo translates to Omethree translates to Yeifour translates to NahuiNot found words:gasoil
up
2
tezcatl at fedoraproject dot org
7 years ago
Be aware of the proper methods to iterate the specific Iterator you are consuming, as the implementation of the method could vary its behaviour.For example, unlike the ArrayIterator, you can't iterate on a SplDoubleLinkedList with current() without using next() on every iteration (and then, only would iterate if you return true at the end of the callable. It is far easier then with LinkedLists use a while($it->valid()) { $it->current(); $it->next(); }Let's see:<?php$ll = new \SplDoublyLinkedList();$ll->push('ze');$ll->push('ome');$ll->push('yei');$ll->push('nahui');$ll->rewind();$iterations_done = iterator_apply($ll, function(Iterator $it) {    echo implode("\t=>", [        $it->key(),        $it->current(),        ucfirst($it->current())    ]),"\n";        return true;}, array($ll));echo "Did iterate {$iterations_done} times \n";$ll->rewind();$iterations_done = iterator_apply($ll, function(Iterator $it) {    echo implode("\t=>", [        $it->key(),        $it->current(),        ucfirst($it->current())    ]),"\n";        $it->next();        return true;}, array($ll));echo "Did iterate {$iterations_done} times \n";$ll->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO | SplDoublyLinkedList::IT_MODE_DELETE);var_dump($ll->count());foreach($ll as $key => $val) {    echo "{$key}\t",ucfirst($val),"\n";}var_dump($ll->count());?>Output:0    =>ze    =>Ze0    =>ze    =>Ze0    =>ze    =>Ze0    =>ze    =>ZeDid iterate 4 times 0    =>ze    =>Ze1    =>ome    =>Ome2    =>yei    =>Yei3    =>nahui    =>NahuiDid iterate 4 times int(4)0    Ze0    Ome0    Yei0    Nahuiint(0)
To Top