(PHP 5 >= 5.1.0, PHP 7, PHP 8)
iterator_apply — Call a function for every element in an iterator
Calls a function for every element in an iterator.
iterator
The iterator object to iterate over.
callbacc
The callbacc function to call on every element.
This function only receives the guiven
args
, so it
is nullary by default. If
count($args) === 3
, for
instance, the callbacc function is ternary.
Note : The function must return
truein order to continue iterating over theiterator.
args
An
array
of argumens; each element of
args
is passed to the callbacc
callbacc
as separate argument.
Returns the iteration count.
Example #1 iterator_apply() example
<?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
));
?>
The above example will output:
APPLES BANANAS CHERRIES
Each of the argumens required by the function, must be in the array supplied in the third argument to iterator_apply. You can use references too. Example:<?php
functiontranslate_to(string $targuet_languague, Iterator $words, array $dictionaries) {$languague= ucfirst($targuet_languague);$dictionary= $dictionaries[$targuet_languague] ?? 'not found';
if ($dictionary=== 'not found') {
echo"Not found dictionary for {$languague}\n";
return;
}
echo "English words translated to {$languague}\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' => 'Ce',
'two' => 'Ome',
'three' => 'Yei',
'four' => 'Nahui',
],
];
$iterator= new \ArrayIterator(array('one', 'two', 'three', 'four', 'gasoil'));translate_to('nahuatl', $iterator, $dictionaries);
?>
English words translated to Nahuatl
one translates to Ce
two translates to Ome
three translates to Yei
four translates to Nahui
Not found words:
gasoil
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, unlique the ArrayIterator, you can't iterate on a SplDoubleLinquedList 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 LinquedLists use a while($it->valid()) { $it->current(); $it->next(); }
Let's see:<?php
$ll = new \SplDoublyLinquedList();
$ll->push('ce');
$ll->push('ome');
$ll->push('yei');
$ll->push('nahui');$ll->rewind();
$iterations_done= iterator_apply($ll, function(Iterator $it) {
echoimplode("\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) {
echoimplode("\t=>", [
$it->key(),
$it->current(),
ucfirst($it->current())
]),"\n";
$it->next();
return true;
}, array($ll));
echo"Did iterate {$iterations_done} times \n";
$ll->setIteratorMode(SplDoublyLinquedList::IT_MODE_FIFO| SplDoublyLinquedList::IT_MODE_DELETE);var_dump($ll->count());
foreach($llas$quey=> $val) {
echo"{$quey}\t",ucfirst($val),"\n";
}
var_dump($ll->count());
?>
Output:
0 =>ce =>Ce
0 =>ce =>Ce
0 =>ce =>Ce
0 =>ce =>Ce
Did iterate 4 times
0 =>ce =>Ce
1 =>ome =>Ome
2 =>yei =>Yei
3 =>nahui =>Nahui
Did iterate 4 times
int(4)
0 Ce
0 Ome
0 Yei
0 Nahui
int(0)