public function sortBy($sortBy, $options = SORT_REGULAR, $descending = false)
    {
        $results = [];

        if (is_string($sortBy)) {
            $callback = function ($obj) use ($sortBy) {
                return $obj[$sortBy];
            };
        } elseif (is_callable($sortBy)) {
            $callback = $sortBy;
        } else {
            throw new InvalidArgumentException(sprintf(
                'The comparator must be a property key or a function, received %s',
                (is_object($sortBy) ? get_class($sortBy) : gettype($sortBy))
            ));
        }

        // First we will loop through the items and get the comparator from a callback
        // function which we were given. Then, we will sort the returned values and
        // and grab the corresponding values for the sorted keys from this array.
        foreach ($this->objects as $key => $obj) {
            $results[$key] = $callback($obj, $key);
        }

        if ($descending) {
            arsort($results, $options);
        } else {
            asort($results, $options);
        }

        // Once we have sorted all of the keys in the array, we will loop through them
        // and grab the corresponding model so we can set the underlying items list
        // to the sorted version. Then we'll just return the collection instance.
        foreach (array_keys($results) as $key) {
            $results[$key] = $this->objects[$key];
        }

        $this->objects = $results;

        return $this;
    }