略微加速

PHP官方手册 - 互联网笔记

PHP - Manual: ArrayIterator

2024-11-13

ArrayIterator 类

(PHP 5, PHP 7, PHP 8)

简介

这个迭代器允许在遍历数组和对象时删除和更新值与键。

当你想多次遍历相同数组时你需要实例化 ArrayObject,然后让这个实例创建一个 ArrayIterator 实例。 当你想遍历相同数组时多次你需要实例 ArrayObject 并且让这个实例创建一个 ArrayIterator 实例,然后使用 foreach 或者手动调用 getIterator() 方法。

类摘要

class ArrayIterator implements SeekableIterator, ArrayAccess, Serializable, Countable {
/* 常量 */
const int STD_PROP_LIST = 1;
const int ARRAY_AS_PROPS = 2;
/* 方法 */
public __construct(array|object $array = [], int $flags = 0)
public append(mixed $value): void
public asort(int $flags = SORT_REGULAR): bool
public count(): int
public current(): mixed
public getArrayCopy(): array
public getFlags(): int
public key(): string|int|null
public ksort(int $flags = SORT_REGULAR): bool
public natcasesort(): bool
public natsort(): bool
public next(): void
public offsetExists(mixed $key): bool
public offsetGet(mixed $key): mixed
public offsetSet(mixed $key, mixed $value): void
public offsetUnset(mixed $key): void
public rewind(): void
public seek(int $offset): void
public serialize(): string
public setFlags(int $flags): void
public uasort(callable $callback): bool
public uksort(callable $callback): bool
public unserialize(string $data): void
public valid(): bool
}

预定义常量

ArrayIterator 标记

ArrayIterator::STD_PROP_LIST

Properties of the object have their normal functionality when accessed as list (var_dump, foreach, etc.).

ArrayIterator::ARRAY_AS_PROPS

可以通过属性访问条目(读写都支持)。

目录

add a noteadd a note

User Contributed Notes 7 notes

up
44
Venelin Vulkov
13 years ago
Another fine Iterator from php . You can use it especially when you have to iterate over objects

<?php
$fruits
= array(
   
"apple" => "yummy",
   
"orange" => "ah ya, nice",
   
"grape" => "wow, I love it!",
   
"plum" => "nah, not me"
);
$obj = new ArrayObject( $fruits );
$it = $obj->getIterator();

// How many items are we iterating over?

echo "Iterating over: " . $obj->count() . " values\n";

// Iterate over the values in the ArrayObject:
while( $it->valid() )
{
    echo
$it->key() . "=" . $it->current() . "\n";
   
$it->next();
}

// The good thing here is that it can be iterated with foreach loop

foreach ($it as $key=>$val)
echo
$key.":".$val."\n";

/* Outputs something like */

Iterating over: 4 values
apple
=yummy
orange
=ah ya, nice
grape
=wow, I love it!
plum=nah, not me

?>

Regards.
up
18
Relakuyae
10 years ago
Need a callback on an iterated value, but don't have PHP 5.4+?  This makes is stupid easy:

<?php
class ArrayCallbackIterator extends ArrayIterator {
  private
$callback;
  public function
__construct($value, $callback) {
   
parent::__construct($value);
   
$this->callback = $callback;
  }

  public function
current() {
   
$value = parent::current();
    return
call_user_func($this->callback, $value);
  }
}
?>

You can use it pretty much exactly as the Array Iterator:

<?php
$iterator1
= new ArrayCallbackIterator($valueList, "callback_function");
$iterator2 = new ArrayCallbackIterator($valueList, array($object, "callback_class_method"));
?>
up
7
Sean Burlington
13 years ago
and to iterate recursively use the (sparsely documented)  RecursiveArrayIterator

<?php

$fruits
= array(
               
"apple" => "yummy",
               
"orange" => "ah ya, nice",
               
"grape" => "wow, I love it!",
                
"plum" => "nah, not me"
               
);

$veg = array("potato" => "chips", "carrot" => "soup");
$grocery = array($fruits, $veg);
$obj = new ArrayObject( $grocery );

$it = new RecursiveIteratorIterator( new RecursiveArrayIterator($grocery));

foreach (
$it as $key=>$val)
echo
$key.":".$val."\n";

?>

Output
--------
apple:yummy
orange:ah ya, nice
grape:wow, I love it!
plum:nah, not me
potato:chips
carrot:soup
up
1
mail at markuszeller dot com
1 year ago
I recommend using ArrayIterator() only in the IteratorAggregate interface on behalf of memory usage.
When not used in that context, the array will be copied on creating a new ArrayIterator().

<?php
class Data implements IteratorAggregate
{
    private array
$array = [];

    public function
__construct()
    {
        for (
$i = 0; $i < 1e5; $i++) $this->array[] = true;
    }

    public function
getIterator(): ArrayIterator
   
{
        return new
ArrayIterator($this->array);
    }
}

$data1 = new Data();
echo
memory_get_usage(), PHP_EOL;
// 4610240

foreach($data1 as $data) {}
echo
memory_get_usage(), PHP_EOL;
// 4610240

foreach($data1 as $data) {}
echo
memory_get_usage(), PHP_EOL;
// 4610240
?>

Memory usage still stay the same.
Now create it without the IteratorAggregate interface.

<?php
$agg
= [];
for (
$i = 0; $i < 1e5; $i++) $agg[] = true;
echo
memory_get_usage(), PHP_EOL;
// 8808720

$iterator1 = new ArrayIterator($agg);
echo
memory_get_usage(), PHP_EOL;
// 13007328

$iterator2 = new ArrayIterator($agg);
echo
memory_get_usage(), PHP_EOL;
// 17205936
?>
up
0
shaman_master at list dot ru
2 years ago
If you want something like `ArrayCallbackIterator` by Relakuyae https://www.php.net/manual/ru/class.arrayiterator.php#106231 , use function `iterator_apply`.
up
-9
daniel dot rutkoski at gmail dot com
6 years ago
<?php
class PrintArray
{
    private
$code = null;

    function
__construct ($val)
    {
       
$this->code = $val;
       
$this->_print();
    }
   
    private function
arrayIterator($val, $grau)
    {
       
$grau++;
       
$arr = new \ArrayIterator($val);
        while (
$arr->valid())
        {
            if(
is_array($arr->current()))
            {
               
$this->arrayIterator($arr->current(), $grau);
            }
            else
            {
               
$this->code .= str_repeat(" ", (4 * $grau)) . $arr->key() . " : " . $arr->current() . PHP_EOL;
            }
           
$arr->next();
        }
    }
   
    private function
_print()
    {
        if (
is_array($this->code))
        {
           
$arr = new \ArrayIterator($this->code);
           
$this->code = 'array(' . PHP_EOL;
            while (
$arr->valid())
            {
                if(
is_array($arr->current()))
                {
                   
$this->arrayIterator($arr->current(), 0);
                }
                else
                {
                   
$this->code .= $arr->key() . " : " . $arr->current() . "\n";
                }
               
$arr->next();
            }
           
$this->code .= ')';
        }
        return
$this;
    }
   
    public function
getVal ()
    {
        return
$this->code;
    }
}

$arr = array(
    array(
       
'ok' => 1, array(9,7,5,9,'a','b'=>array(1,2)),
       
'error' => 2, array('h','u','o')
    )
    ,
'array'
);
$pArray = new PrintArray($arr);
var_dump($pArray->getVal());
up
-28
foobuilder at gmail dot com
11 years ago
Unsetting all keys of an ArrayItem within foreach will always leave the second key:

<?php
$items
= new ArrayObject(range(0, 9));

while (list(
$k, $v) = each($items)) {
    unset(
$items[$k]);
}

print_r($items);

//  ArrayIterator Object
//  (
//      [storage:ArrayIterator:private] => Array
//          (
//              [1] => 1
//          )
//  )
?>

I'm not sure if this is a bug as unsetting keys within foreach is usually a bad idea to begin with (use while instead), but it's something to be aware of.

官方地址:https://www.php.net/manual/en/class.arrayiterator.php

北京半月雨文化科技有限公司.版权所有 京ICP备12026184号-3