/** * Concatenates one or more foreach-able object into an Iterator. * If no objects provided, returns an empty iterator. * \AppendIterators provided will be deep copied. * This means changes to \AppendIterator parameters will not be reflected * in the resulting \Iterator. * @return \Iterator */ public static function concat() { $argCount = \func_num_args(); if ($argCount === 0) { return new \EmptyIterator(); } elseif ($argCount === 1) { return Iterators::ensureIsIterator(\func_get_args()[0]); } else { $retval = new \AppendIterator(); //Workaround for AppendIterator bugs //https://bugs.php.net/bug.php?id=49104 //https://bugs.php.net/bug.php?id=62212 $retval->append(new \ArrayIterator([0])); unset($retval->getArrayIterator()[0]); $recursiveAttach = static function ($iter) use(&$recursiveAttach, $retval) { foreach ($iter as $concatedIter) { if ($concatedIter instanceof \AppendIterator) { $recursiveAttach($concatedIter->getArrayIterator()); } elseif ($concatedIter instanceof \EmptyIterator) { //Do not add it. } else { $retval->append($concatedIter); } } return $retval; }; return (new \Yasca\Core\FunctionPipe())->wrap(\func_get_args())->pipe([Iterators::_class, 'ensureIsIterator'])->pipe([Iterators::_class, 'select'], [Iterators::_class, 'ensureIsIterator'])->pipe($recursiveAttach)->unwrap(); } }
public function from($values){ if ($this->iterator === null){ $this->iterator = Iterators::ensureIsIterator($values); //TODO: More intelligent handling of RecursiveIterators if ($this->iterator instanceof \RecursiveIterator){ $this->iterator = new \RecursiveIteratorIterator($this->iterator); } } else { throw new IteratorException('Iterator already assigned'); } return $this; }