index = 0; // Keep only reference of the array $this->array = &$array; /* We need a copy of the keys in order for our code to work for associative arrays as well. */ $this->keys = array_keys($array); $this->size = sizeof($this->keys); } function rewind() { $this->index = 0; } public function get_size(){ return $this->size; } private function fetch(){ $value = $this->array[$this->keys[$this->seek]]; if ( !is_null($this->mapper) ) $value = call_user_func($this->mapper, $value); if ( !is_null($this->filter) ) { while ( !call_user_func($this->filter, $value) ){ $this->seek++; if ( $this->seek < $this->size ) $value = $this->array[$this->keys[$this->seek]]; else break; } $this->index = $this->seek; } $this->last = $value; return $this->index < $this->size; } function current() { return $this->last; } function key() { if ( $this->valid() ) return $this->keys[$this->index]; } function next() { ++$this->index; $this->seek = $this->index; } function valid() { return ($this->index < $this->size) && $this->fetch(); } public function filter($callable){ $this->filter = $callable; } public function map($callable) { $this->mapper = $callable; } } function ifilter($function, &$iterable) { $iterator = new Generator($iterable); $iterator->filter($function); return $iterator; } function ifilterfalse($function, &$iterable) { return ifilter(function($item) use($function) { return !call_user_func($function, $item);}, $iterable); } function imap($function, &$iterable) { $iterator = new Generator($iterable); $iterator->map($function); return $iterator; } /* No generator implementation for now but quite convenient! */ function zip(){ $arrays = func_get_args(); $loop = TRUE; $minimum = min(array_map('sizeof', $arrays)); $zipped = array(); $counter = 0; $values = array(); $array_loop = range(0, func_num_args()-1); while ( $counter < $minimum ){ $values = array(); if ( $counter == 0 ){ foreach($array_loop as $index) $values[] = current($arrays[$index]); } else { foreach($array_loop as $index) $values[] = next($arrays[$index]); } $zipped[] = $values; $counter++; } return $zipped; } /************/ /* Examples */ /************/ $a = range(1, 20); print "-- ifilter\n"; foreach(ifilter(function($n){ return $n % 3 == 0; }, $a) as $key => $value){ print sprintf("%2d -> %s", $key, $value); print "\n"; } print "-- ifilterfalse\n"; foreach(ifilterfalse(function($n){ return $n % 3 == 0; }, $a) as $key => $value){ print sprintf("%2d -> %s", $key, $value); print "\n"; } print "-- imap\n"; foreach(imap(function($n){ return $n * $n; }, $a) as $key => $value){ print sprintf("%2d -> %s", $key, $value); print "\n"; } var_dump(zip(range(1,20), range(3,22), range(5,24)));