PHP Conference Japan 2024

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,则回调函数为三元函数。

注意: 该函数必须返回 true 才能继续迭代 $iterator

args

一个 array 类型的参数数组;$args 的每个元素都作为单独的参数传递给回调函数 $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() - 将用户提供的函数应用于数组的每个成员

添加注释

用户贡献的注释 3 条注释

tezcatl at fedoraproject dot org
6 年前
函数所需的每个参数都必须位于传递给 iterator_apply 的第三个参数中的数组中。您也可以使用引用。示例

<?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
gasoil
tezcatl at fedoraproject dot org
6 年前
请注意您正在使用的特定迭代器的正确迭代方法,因为该方法的实现可能会改变其行为。

例如,与 ArrayIterator 不同,您不能在不使用 next() 进行每次迭代的情况下使用 current() 迭代 SplDoubleLinkedList(然后,只有在可调用对象结束时返回 true 时才会迭代。使用链表时,使用 while($it->valid()) { $it->current(); $it->next(); } 会容易得多。

让我们看看

<?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
"迭代次数为 {$iterations_done} 次\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
"迭代次数为 {$iterations_done} 次\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());
?>

输出

0 =>ze =>Ze
0 =>ze =>Ze
0 =>ze =>Ze
0 =>ze =>Ze
迭代次数为 4 次
0 =>ze =>Ze
1 =>ome =>Ome
2 =>yei =>Yei
3 =>nahui =>Nahui
迭代次数为 4 次
int(4)
0 Ze
0 Ome
0 Yei
0 Nahui
int(0)
ycgambo at outlook dot com
7年前
$args 是一个数组,其每个元素都作为单独的参数传递给回调函数。

所以这是获取参数的正确方法

<?php
$ai
= new ArrayIterator(range(0, 2));

iterator_apply($ai, function() {
var_dump(func_get_args()); // 使用此函数
return true;
}, array(
1, 2));
?>

输出

array(2) {
[0] =>
int(1)
[1] =>
int(2)
}
array(2) {
[0] =>
int(1)
[1] =>
int(2)
}
array(2) {
[0] =>
int(1)
[1] =>
int(2)
}

--------------------------------------------------
或者列出每个参数

<?php
$ai
= new ArrayIterator(range(0, 2));

iterator_apply($ai, function($arg1, $arg2, $arg3) {
var_dump([$arg1, $arg2, $arg3]);
return
true;
}, array(
1, 2));
?>

输出相同。
To Top