def groupBy(self, val):
        """
        Groups the object's values by a criterion. Pass either a string
        attribute to group by, or a function that returns the criterion.
        """

        def by(result, key, value):
            if key not in result:
                result[key] = []
            result[key].append(value)

        res = self._group(self.obj, val, by)

        return self._wrap(res)