A very useful use case for RecusiveIteratorIterator in combination with RecursiveArrayIterator is to replace array values on a multidimensional array at any level deep.
Usually, array_walk_recursive would be used to replace values deep within arrays, but unfortunately this only works when there is a standard key value pair - in other words, array_walk_recursive ONLY VISITS LEAF NODES, NOT arrays.
So to get around this, the iterators can be used in this way:
<?php
$array = [
'test' => 'value',
'level_one' => [
'level_two' => [
'level_three' => [
'replace_this_array' => [
'special_key' => 'replacement_value',
'key_one' => 'testing',
'key_two' => 'value',
'four' => 'another value'
]
],
'ordinary_key' => 'value'
]
]
];
$arrayIterator = new \RecursiveArrayIterator($array);
$recursiveIterator = new \RecursiveIteratorIterator($arrayIterator, \RecursiveIteratorIterator::SELF_FIRST);
foreach ($recursiveIterator as $key => $value) {
if (is_array($value) && array_key_exists('special_key', $value)) {
// Here we replace ALL keys with the same value from 'special_key'
$replaced = array_fill(0, count($value), $value['special_key']);
$value = array_combine(array_keys($value), $replaced);
// set a new key
$value['new_key'] = 'new value';
// Get the current depth and traverse back up the tree, saving the modifications
$currentDepth = $recursiveIterator->getDepth();
for ($subDepth = $currentDepth; $subDepth >= 0; $subDepth--) {
// Get the current level iterator
$subIterator = $recursiveIterator->getSubIterator($subDepth);
// If we are on the level we want to change, use the replacements ($value) other wise set the key to the parent iterators value
$subIterator->offsetSet($subIterator->key(), ($subDepth === $currentDepth ? $value : $recursiveIterator->getSubIterator(($subDepth+1))->getArrayCopy()));
}
}
}
return $recursiveIterator->getArrayCopy();
// return:
$array = [
'test' => 'value',
'level_one' => [
'level_two' => [
'level_three' => [
'replace_this_array' => [
'special_key' => 'replacement_value',
'key_one' => 'replacement_value',
'key_two' => 'replacement_value',
'four' => 'replacement_value',
'new_key' => 'new value'
]
],
'ordinary_key' => 'value'
]
]
];
?>
The key is in traversing back up the tree to save the changes at that level - simply calling $recursiveIterator->offsetSet(); will only set a key on the root array.
PHP.mk документација
RecursiveIteratorIterator
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Патека
class.recursiveiteratoriterator.php
Локална патека за оваа страница.
Извор
php.net/manual/en
Оригиналниот HTML се реупотребува и локално се стилизира.
Режим
Прокси + превод во позадина
Кодовите, табелите и белешките остануваат читливи во истиот тек.
Референца
class.recursiveiteratoriterator.php
RecursiveIteratorIterator
Референца за `class.recursiveiteratoriterator.php` со подобрена типографија и навигација.
Класата RecursiveIteratorIterator
класата mysqli_driver
Вовед
Може да се користи за итерирање низ рекурзивни итератори.
Синопсис на класата
/* Константи */
/* Методи */
public __construct(Траверзабилно
}$iterator, int $mode = RecursiveIteratorIterator::LEAVES_ONLY, int $flags = 0)Содржина
- RecursiveIteratorIterator::beginChildren — Започни деца
- RecursiveIteratorIterator::beginIteration — Започни итерација
- RecursiveIteratorIterator::callGetChildren — Земи деца
- RecursiveIteratorIterator::callHasChildren — Има деца
- RecursiveIteratorIterator::__construct — Конструирај RecursiveIteratorIterator
- RecursiveIteratorIterator::current — Пристапи до вредноста на тековниот елемент
- RecursiveIteratorIterator::endChildren — Крај деца
- RecursiveIteratorIterator::endIteration — Крај на итерација
- RecursiveIteratorIterator::getDepth — Добиј ја тековната длабочина на рекурзивната итерација
- RecursiveIteratorIterator::getInnerIterator — Добиј внатрешен итератор
- RecursiveIteratorIterator::getMaxDepth — Добиј максимална длабочина
- RecursiveIteratorIterator::getSubIterator — Тековниот активен под-итератор
- RecursiveIteratorIterator::key — Пристапи до тековниот клуч
- RecursiveIteratorIterator::next — Помести се напред до следниот елемент
- RecursiveIteratorIterator::nextElement — Следен елемент
- RecursiveIteratorIterator::rewind — Помести го итераторот на првиот елемент од внатрешниот итератор на највисоко ниво
- RecursiveIteratorIterator::setMaxDepth — Постави максимална длабочина
- RecursiveIteratorIterator::valid — Провери дали тековната позиција е валидна
Белешки од корисници Управување со PDO конекции
Анонимен ¶
пред 9 години
Adil Baig @ AIdezigns ¶
пред 14 години
A very important thing to note about \RecursiveIteratorIterator is that it returns a flattened array when used with the iterator_to_array function. Ex:
<?php
$arr = array('Zero', 'name'=>'Adil', 'address' => array( 'city'=>'Dubai', 'tel' => array('int' => 971, 'tel'=>12345487)), '' => 'nothing');
$iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($arr));
var_dump(iterator_to_array($iterator,true));
?>
This code will return :
array(6) {
[0]=>
string(4) "Zero"
["name"]=>
string(4) "Adil"
["city"]=>
string(5) "Dubai"
["int"]=>
int(91)
["tel"]=>
int(12345487)
[""]=>
string(7) "nothing"
}
To get the non-flattened proper array use the getArrayCopy() method, like so :
$iterator->getArrayCopy()
This will return
array(4) {
[0]=>
string(4) "Zero"
["name"]=>
string(4) "Adil"
["address"]=>
array(2) {
["city"]=>
string(5) "Dubai"
["tel"]=>
array(2) {
["int"]=>
int(91)
["tel"]=>
int(12345487)
}
}
[""]=>
string(7) "nothing"
}
aidan на php точка net ¶
пред 15 години
This example demonstrates using the getDepth() method with a RecursiveArrayIterator.
<?php
$tree = array();
$tree[1][2][3] = 'lemon';
$tree[1][4] = 'melon';
$tree[2][3] = 'orange';
$tree[2][5] = 'grape';
$tree[3] = 'pineapple';
print_r($tree);
$arrayiter = new RecursiveArrayIterator($tree);
$iteriter = new RecursiveIteratorIterator($arrayiter);
foreach ($iteriter as $key => $value) {
$d = $iteriter->getDepth();
echo "depth=$d k=$key v=$value\n";
}
?>
The output of this would be:
Array
(
[1] => Array
(
[2] => Array
(
[3] => lemon
)
[4] => melon
)
[2] => Array
(
[3] => orange
[5] => grape
)
[3] => pineapple
)
depth=2 k=3 v=lemon
depth=1 k=4 v=melon
depth=1 k=3 v=orange
depth=1 k=5 v=grape
depth=0 k=3 v=pineapple
Michiel Brandenburg ¶
пред 16 години
You can use this to quickly find all the files (recursively) in a certain directory. This beats maintaining a stack yourself.
<?php
$directory = "/tmp/";
$fileSPLObjects = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($directory),
RecursiveIteratorIterator::CHILD_FIRST
);
try {
foreach( $fileSPLObjects as $fullFileName => $fileSPLObject ) {
print $fullFileName . " " . $fileSPLObject->getFilename() . "\n";
}
}
catch (UnexpectedValueException $e) {
printf("Directory [%s] contained a directory we can not recurse into", $directory);
}
?>
Note: if there is a directory contained within the directory you are searching in that you have no access to read an UnexpectedValueException will be thrown (leaving you with an empty list).
Note: objects returned are SPLFileObjects
gerry at king-foo dot be ¶
пред 11 години
Carefull when using iterator_to_array(). Because it flattens down your subiterators, elements with the same keys will overwrite eachother.
For example:
<?php
$iterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator([
['foo', 'bar'],
['baz', 'qux']
])
);
foreach ($iterator as $element) {
echo $element;
}
?>
This will output all 4 elements as expected:
string(3) "foo"
string(3) "bar"
string(3) "baz"
string(3) "qux"
While doing:
<?php
var_dump(iterator_to_array($iterator));
?>
will output an array with only the last 2 elements:
array(2) {
[0]=>
string(3) "baz"
[1]=>
string(3) "qux"
}
7 белешки ¶
пред 15 години
This class operates on a tree of elements, which is build by nesting recursive iterators into one another.
Thus you might say it is an iterator over iterators. While traversing those, the class pushes the iterators on a stack while traversing down to a leaf and removes them from the stack while going back up.
fengdingbo at gmail dot com ¶
12 години пред
if you want traversal directory。
<?php
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator("./")) as $key=>$val)
{
echo $key,"=>",$val,"\n";
}
?>