public function asArray($fields = [], $valuesOnly = false, $flat = false)
    {
        if ($flat && 1 != count($fields)) {
            throw new TypeError(
                "'flat' is valid when asArray is called".
                ' with exactly one field.'
            );
        }
        if ($flat && !$valuesOnly) {
            throw new TypeError(
                "'flat' is valid when asArray ".
                'is called with valuesOnly=true.'
            );
        }
        $clone = $this->_clone();
        $clone->_fields = $fields;
        $clone->query->setValueSelect($fields);

        $clone->resultMapper = ($valuesOnly) ? ArrayValueMapper::class :
            ArrayMapper::class;
        if ($flat) {
            $clone->resultMapper = ArrayFlatValueMapper::class;
        }

        return $clone;
    }