2012-06-17 4 views
15

Я хочу использовать ассоциативный массив с PHP итератора:метод Next Итератор для ассоциативного массива

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

это возможно?

Я определил эти методы:

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]); 
    } 

Проблема заключается в том, что не перебирать правильно. Я получаю только один элемент.

Я думаю, что это из-за кода ++$this->_position в методе next(), который не имеет никакого эффекта, потому что _position - это строка (ключ ассоциативного массива).

так как я могу перейти к следующему элементу массива этого типа?

+4

Из любопытства, почему вы просто не используя [ ArrayIterator] (http://us.php.net/arrayiterator)? – nickb

+0

Не могли бы вы предоставить больше кода? Это будет: а) часть, в которой вы говорите: «класс XYZ реализует Iterator» b) ту часть, где вы (пытаетесь) ее использовать. – Niko

+1

«Я определил эти методы» - это называется «скопировано как-есть из документации» ;-) – zerkms

ответ

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

В цикле foreach я полагаю, что это не вернет ключ - только численное представление. Верный? –

+0

@ Rambo, возможно, захочет проверить, что редактирование – OGHaza

+0

@OGHaza спасибо. Я думаю, что его последнее редактирование кажется мне подходящим? У моего исходного кода не было ошибки, но я думаю, что его последнее редактирование немного лучше. – 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

Этот код был бы еще более полезен, если бы он был прокомментирован и объяснен, поэтому другие, кроме OP, могли бы извлечь выгоду из ваших знаний. – Haroon

+1

@Haroon: он использует только базовые конструкции. Если кто-то может это получить - тогда пришло время изучить основы – zerkms

+2

Я действительно, действительно не понимаю, зачем еще изобретать колесо ... Используя ArrayIterator, полученный от ArrayObject, что ассоциативный массив был превращен в намного проще. .. И не нужно записывать наш собственный ArrayIterator ... – shadyyx

5

Почему не создавая ArrayObject от Вашего ассоциативного Array? Тогда Вы можете getIterator() от этого ArrayObject и называют key(), next() и т.д. на нем, как вы хотите ...

Некоторые примеры:

$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

Я знаю, что это старый вопрос, но это может быть так же просто, как

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; 
} 

Я знаю, что аналогичный ответ был вывешен @zerkms но имхо то не работает, если объект уже построен и у вас есть функциональность, которая расширяет спектр

Смежные вопросы