From: Florent Bruneau Date: Tue, 19 Aug 2008 20:42:39 +0000 (+0200) Subject: Add a generic PlArrayIterator. X-Git-Tag: core/1.0.0~33 X-Git-Url: http://git.polytechnique.org/?a=commitdiff_plain;h=63f00a3fb4e2c83167b8293d575da8ac1778709b;p=platal.git Add a generic PlArrayIterator. Signed-off-by: Florent Bruneau --- diff --git a/classes/plarrayiterator.php b/classes/plarrayiterator.php new file mode 100644 index 0000000..d249b8a --- /dev/null +++ b/classes/plarrayiterator.php @@ -0,0 +1,125 @@ +array =& $array; + $this->depth = $depth; + $this->_total = $this->count($array, $depth - 1); + $this->_pos = 0; + $this->_first = false; + $this->_last = false; + + for ($i = 0 ; $i < $depth ; ++$i) { + if ($i == 0) { + $this->_its[] = $array; + } else { + $this->_its[] = current($this->_its[$i - 1]); + } + reset($this->_its[$i]); + } + } + + private function count(array &$array, $depth) + { + if ($depth == 0) { + return count($array); + } else { + $sum = 0; + foreach ($array as &$item) { + $sum += $this->count($item, $depth - 1); + } + return $sum; + } + } + + private function nextArray($depth) + { + if ($depth == 0) { + return; + } + $this->_its[$depth] = next($this->_its[$depth - 1]); + if ($this->_its[$depth] === false) { + $this->nextArray($depth - 1); + if ($this->_its[$depth - 1] === false) { + return; + } + $this->_its[$depth] = current($this->_its[$depth - 1]); + } + reset($this->_its[$depth]); + } + + public function next() + { + ++$this->_pos; + $this->_first = ($this->_total > 0 && $this->_pos == 1); + $this->_last = ($this->_pos == $this->_total); + if ($this->_pos > $this->_total) { + return null; + } + + $val = current($this->_its[$this->depth - 1]); + if ($val === false) { + $this->nextArray($this->depth - 1); + $val = current($this->_its[$this->depth - 1]); + if ($val === false) { + return null; + } + } + $keys = array(); + for ($i = 0 ; $i < $this->depth ; ++$i) { + $keys[] = key($this->_its[$i]); + } + next($this->_its[$this->depth - 1]); + return array('keys' => $keys, + 'value' => $val); + } + + public function total() + { + return $this->_total; + } + + public function first() + { + return $this->_first; + } + + public function last() + { + return $this->_last; + } +} + +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: +?>