raw = $results; $this->traversable = $results; } /** * Group the results by a certain field. * * @param string $field * @return TableModelResult */ public function group(string $field): self { // First make sure all data is fetched $this->allToArray(); // Afterwards build a grouped array $grouped = []; foreach ($this->result->getIterator() as $key => $val) { // Check if this group exists within the results if (isset($val[$field])) { // Name of the group $fieldSelector = $val[$field]; // If the group has never been found before, add the array if (!isset($grouped[$fieldSelector])) $grouped[$fieldSelector] = []; unset($val[$field]); $grouped[$fieldSelector][] = $val; } } $this->result->exchangeArray($grouped); return $this; } /** * Convert the result into an array * * @return array */ public function toArray(): array { // First make sure all data is fetched $this->allToArray(); // And return a copy return $this->result->getArrayCopy(); } /** * Retrieve an external iterator * @link https://php.net/manual/en/iteratoraggregate.getiterator.php * @return Traversable An instance of an object implementing Iterator or * Traversable * @since 5.0.0 */ public function getIterator(): Traversable { return $this->traversable; } private function allToArray(): void { // If the input has already been fetched, ignore it if ($this->fullyFetched) return; $result = []; foreach ($this->raw as $key => $val) { // Clear out all numeric keys foreach ($val as $recKey => $recVal) if (is_numeric($recKey)) unset($val[$recKey]); $result[$key] = $val; } // Set the variable $this->result = new ArrayObject($result); // Afterwards modify the traversable $this->traversable = $this->result->getIterator(); // Set fullyFetched to true so it doesn't get fetched again $this->fullyFetched = true; } }