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);
?>

英文單字翻譯成納瓦特爾語
one 翻譯成 Ze
two 翻譯成 Ome
three 翻譯成 Yei
four 翻譯成 Nahui

找不到的單字
gasoil
tezcatl at fedoraproject dot org
6 年前
請注意迭代您正在使用的特定迭代器的正確方法,因為方法的實作可能會改變其行為。

例如,與 ArrayIterator 不同,您無法在 SplDoubleLinkedList 上使用 current() 迭代,而不必在每次迭代時使用 next()(然後,只有在可呼叫函式結尾傳回 true 時才會迭代)。如果使用 LinkedList,則使用 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
"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());
?>

輸出

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