PHP: iterator_apply - Manual
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
iterator_apply — Call a function for every element in an iterator
Description
Parameters
iterator-
The iterator object to iterate over.
callback-
The callback function to call on every element. This function only receives the given
args, so it is nullary by default. Ifcount($args) === 3, for instance, the callback function is ternary.Note: The function must return
truein order to continue iterating over theiterator. args-
An array of arguments; each element of
argsis passed to the callbackcallbackas separate argument.
Return Values
Returns the iteration count.
Examples
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:
See Also
- array_walk() - Apply a user supplied function to every member of an array
Found A Problem?
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:
<?php
function 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 Nahuatl
one translates to Ze
two translates to Ome
three translates to Yei
four translates to Nahui
Not found words:
gasoiltezcatl 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 =>Ze
0 =>ze =>Ze
0 =>ze =>Ze
0 =>ze =>Ze
Did iterate 4 times
0 =>ze =>Ze
1 =>ome =>Ome
2 =>yei =>Yei
3 =>nahui =>Nahui
Did iterate 4 times
int(4)
0 Ze
0 Ome
0 Yei
0 Nahui
int(0)