TopicIterator

HTML

<ol id="results">
</ol>

TypeScript

class TopicIterator<TItem, TTopics> {
    private _getTopics?: (item: TItem) => TTopics[];
    private _isRelevant: (itemTopics: TTopics[]) => boolean;

    search(accessor: (item: TItem) => TTopics[]): TopicIterator<TItem, TTopics> {
        if (!(accessor instanceof Function))
            throw new TypeError("Invalid parameter, pass a function")
        this._getTopics = accessor;
        return this;
    }

    forAll(...topics: TTopics[]): TopicIterator<TItem, TTopics> {
        if (topics.length == 0)
            throw new TypeError("Specify at least one topic!");
        if (this._isRelevant)
            throw new TypeError("Specify your topics only once!");
        this._isRelevant = (itemTopics: TTopics[]) => topics.every(topic => itemTopics.includes(topic));
        return this;
    }

    forAny(...topics: TTopics[]): TopicIterator<TItem, TTopics> {
        if (topics.length == 0)
            throw new TypeError("Specify at least one topic!");
        if (this._isRelevant)
            throw new TypeError("Specify your topics only once!");
        this._isRelevant = itemTopics => topics.some(topic => itemTopics.includes(topic));
        return this;
    }

    *in(collection: TItem[]): Generator<TItem, void, unknown> {
        if (!collection || !collection[Symbol.iterator])
            throw new TypeError("Cannot iterate data");
        if (!this._getTopics)
            throw new TypeError("Specify search location (call search method and pass an accessor function)");
        if (!this._isRelevant)
            throw new TypeError("Specify topics to find (call forAll or forAny and pass them)");

        for (const item of collection) {
            if (this._isRelevant(this._getTopics(item)))
                yield item;
        }
    }
}

interface Item {
    name: string;
    topics: string[];
}

// Spieldaten
const itemList: Item[] = [
    {name: "Hugo", topics: ["Foo", "Baz"]},
    {name: "Otto", topics: ["Foo", "Bar"]},
    {name: "Paul", topics:...