2012-06-17 13 views
15

Quiero utilizar una matriz asociativa con el iterador PHP:método siguiente iterador de conjunto asociativo

http://php.net/manual/en/class.iterator.php

es posible?

que definen estos métodos:

public function rewind(){  
    reset($this->_arr); 
    $this->_position = key($this->_arr); 
    } 

    public function current(){  
    return $this->_arr[$this->_position]; 
    } 

    public function key(){ 
    return $this->_position; 
    } 

    public function next(){  
    ++$this->_position; 
    } 

    public function valid(){  
    return isset($this->_arr[$this->_position]); 
    } 

el problema es que no iterar correctamente. Solo tengo un elemento.

Creo que es por el código ++$this->_position en el método next() que no tiene ningún efecto porque _position es una cadena (clave de la matriz asociativa).

Entonces, ¿cómo puedo ir al siguiente elemento de este tipo de matriz?

+4

Por curiosidad, ¿por qué no te utilizando una [ ArrayIterator] (http://us.php.net/arrayiterator)? – nickb

+0

¿Puedes mostrar más de tu código? Eso sería a) la parte en la que dices 'clase XYZ implementa Iterator' b) la parte donde (intentas) usarla. – Niko

+1

"Definí estos métodos" - se llama "copiado como está de la documentación" ;-) – zerkms

Respuesta

27
function rewind() { 
    reset($this->_arr); 
} 

function current() { 
    return current($this->_arr); 
} 

function key() { 
    return key($this->_arr); 
} 

function next() { 
    next($this->_arr); 
} 

function valid() { 
    return key($this->_arr) !== null; 
} 
+0

En un bucle 'foreach', supongo que esto no devolverá una clave, solo una representación numérica. ¿Correcto? –

+0

@Rambo, querría comprobar que editar – OGHaza

+0

@OGHaza gracias. Creo que su última edición me parece bien? Mi código de origen no tenía un error, pero creo que me gusta su última edición ligeramente mejor. – goat

2

http://ideone.com/Fxt0j

class myIterator implements Iterator { 
    private $position = 0; 
    private $keys; 

    public function __construct(array $arr) { 
     $this->array = $arr; 
     $this->keys = array_keys($arr); 
     $this->position = 0; 
    } 

    function rewind() { 
     $this->position = 0; 
    } 

    function current() { 
     return $this->array[$this->key()]; 
    } 

    function key() { 
     return $this->keys[$this->position]; 
    } 

    function next() { 
     ++$this->position; 
    } 

    function valid() { 
     return isset($this->keys[$this->position]); 
    } 
} 

$it = new myIterator(array(
     'a' => "firstelement", 
     'b' => "secondelement", 
     'c' => "lastelement", 
    )); 

foreach($it as $key => $value) { 
    var_dump($key, $value); 
    echo "\n"; 
} 
+3

Este código sería aún más útil si se comentara y explicara, por lo que otros, aparte de OP, podrían beneficiarse de su conocimiento. – Haroon

+1

@Haroon: solo usa construcciones básicas. Si alguien pudiera obtenerlo, entonces es el momento de aprender los conceptos básicos – zerkms

+2

Realmente, realmente no entiendo por qué reinventar la rueda ... Usando ArrayIterator obtuve de ArrayObject que una matriz asociativa se convirtió en mucho más simple. .. Y no hay necesidad de escribir nuestro propio ArrayIterator ... – shadyyx

5

Por qué no crear un ArrayObject de su asociativo Array? A continuación, puede getIterator() de esta ArrayObject y llame key(), etc next() en él como desee ...

Algunos ejemplos:

$array = array('one' => 'ONE', 'two' => 'TWO', 'three' = 'THREE'); 
// create ArrayObject and get it's iterator 
$ao = new ArrayObject($my_array); 
$it = $ao->getIterator(); 
// looping 
while($it->valid()) { 
    echo "Under key {$it->key()} is value {$it->current()}"; 
    $it->next(); 
} 

ArrayObject
ArrayIterator

1
class MyItrator implements Iterator 
{ 
    private $_arr; 

    public function __construct(array $arr) 
    { 
     $this->_arr = $arr; 
    } 


    public function rewind() 
    { 
     reset($this->_arr); 
    } 

    public function current() 
    { 
     return current($this->_arr); 
    } 

    public function key() 
    { 
     return key($this->_arr); 
    } 

    public function next() 
    { 
     next($this->_arr); 
    } 

    public function valid() 
    { 
     return isset($this->_arr[key($this->_arr)]); 
    } 
} 
0

Sé que esto es una vieja pregunta, pero puede ser tan simple como

public function current() 
{ 
    return $this->array[array_keys($this->array)[$this->position]]; 
} 

public function next() 
{ 
    ++$this->position; 
} 

public function key() 
{ 
    return array_keys($this->array)[$this->position]; 
} 

public function valid() 
{ 
    return array_key_exists($this->position, array_keys($this->array)[$this->position]); 
} 

public function rewind() 
{ 
    $this->position = 0; 
} 

sé una respuesta similar fue publicada por @zerkms pero en mi humilde opinión esto no funciona si el objeto ya está construido y tiene la funcionalidad que se extiende la matriz