<commit_before>function isIterator<T>(obj: any): obj is Iterator<T> {
    const it = <Iterator<T>>obj;
    return it.next !== undefined;
}

export interface Grouping<T, TValue> {
    Key: T,
    Values: Enumerable<TValue>
}

export class Enumerable<T> implements Iterable<T> {
    protected iteratorGetter: () => Iterator<T>;

    public static Of<T>(source: T[] | Iterator<T>): Enumerable<T> {
        if (isIterator(source)) {
            return new Enumerable<T>(() => source);
        }
        return new Enumerable<T>(() => new EmptyIterator<T>(source));
    }

    protected static makeIterator<T, TReturnIteratorType>(sourceIterator: Iterator<T>, next: ((sourceIterator: Iterator<T>) => IteratorResult<TReturnIteratorType>)) {
        const iterator: Iterator<TReturnIteratorType> = {
            next: function () {
                return next(sourceIterator);
            }
        }
        if (sourceIterator.return) {
            iterator.return = <any>(sourceIterator.return);
        }
        return iterator;
    }

    protected constructor(iteratorGetter: () => Iterator<T>) {
        this.iteratorGetter = iteratorGetter;
    }

    [Symbol.iterator]() {
        return this.iteratorGetter();
    }

    public Aggregate<TAccumulate, TResult>(
        seed: TAccumulate,
        accumulator: (accumulate: TAccumulate, next: T) => TAccumulate,
        resultSelector: (item: TAccumulate) => TResult = (result) => <TResult><any>result
    ): TResult {
        this.ForEach(a => {
            seed = accumulator(seed, a);
        });

        return resultSelector(seed);
    }

    public All(predicate: (item: T) => boolean) {
        return !this.Any(i => !predicate(i));
    }

    public Any(): boolean;
    public Any(predicate: ((item: T) => boolean)): boolean;
    public Any(predicate?: (item: T) => boolean) {
        let enumerable = <Enumerable<T>>this;
        if (predicate) {<commit_msg>Fix Aggregate's overloads and start some documentation<commit_after>function isIterator<T>(obj: any): obj is Iterator<T> {
    const it = <Iterator<T>>obj;
    return it.next !== undefined;
}

export interface Grouping<T, TValue> {
    Key: T,
    Values: Enumerable<TValue>
}

export class Enumerable<T> implements Iterable<T> {
    protected iteratorGetter: () => Iterator<T>;

    /**
     * Creates an Enumerable which encapsulates the provided source
     * @param source Either an array of T, or an Iterator<T>. An Iterator<T> can be manually created, or using function generators.
     */
    public static Of<T>(source: T[] | Iterator<T>): Enumerable<T> {
        if (isIterator(source)) {
            return new Enumerable<T>(() => source);
        }
        return new Enumerable<T>(() => new EmptyIterator<T>(source));
    }

    protected static makeIterator<T, TReturnIteratorType>(sourceIterator: Iterator<T>, next: ((sourceIterator: Iterator<T>) => IteratorResult<TReturnIteratorType>)) {
        const iterator: Iterator<TReturnIteratorType> = {
            next: function () {
                return next(sourceIterator);
            }
        }
        if (sourceIterator.return) {
            iterator.return = <any>(sourceIterator.return);
        }
        return iterator;
    }

    protected constructor(iteratorGetter: () => Iterator<T>) {
        this.iteratorGetter = iteratorGetter;
    }

    [Symbol.iterator]() {
        return this.iteratorGetter();
    }

    /**
     * Aggregates the enumerable with an initial seed and an accumulator function
     * @param seed The initial accumulator value
     * @param accumulator The accumulator function which is invoked on each element.
     */
    public Aggregate<TAccumulate>(seed: TAccumulate, accumulator: (accumulate: TAccumulate, next: T) => TAccumulate): TAccumulate;

    /**
     * Aggregates the enumerable with an initial seed and an accumulator function
     * @param seed The initial accumulator value
     * @param accumulator The accumulator function which is invoked on each element.
     * @param resultSelector A function which takes the final result and applies a transform.
     */
    public Aggregate<TAccumulate, TResult>(seed: TAccumulate, accumulator: (accumulate: TAccumulate, next: T) => TAccumulate, resultSelector: (item: TAccumulate) => TResult): TResult;
    public Aggregate<TAccumulate, TResult>(
        seed: TAccumulate,
        accumulator: (accumulate: TAccumulate, next: T) => TAccumulate,
        resultSelector?: (item: TAccumulate) => TResult
    ): TAccumulate | TResult {
        this.ForEach(a => {
            seed = accumulator(seed, a);
        });

        if (!resultSelector) {
            return seed;
        } else {
            return resultSelector(seed);
        }
    }

    public All(predicate: (item: T) => boolean) {
        return !this.Any(i => !predicate(i));
    }

    public Any(): boolean;
    public Any(predicate: ((item: T) => boolean)): boolean;
    public Any(predicate?: (item: T) => boolean) {
        let enumerable = <Enumerable<T>>this;
        if (predicate) {
{'fraction_non_alphanumeric': 0.12410643367752185, 'fraction_numerical': 0.0, 'mean_word_length': 2.8509174311926606, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3051998', 'n_tokens_mistral': 1479, 'n_tokens_neox': 1453, 'n_words': 384}