Javascript IteratorWrapper

Date: 2024-08-15
(() => {

    function from(iterable) {
        return new IteratorWrapper(iterable);
    }

    function* map(iter, f) {
        for (let x of iter) {
            yield f(x);
        }
    }

    function* filter(iter, f) {
        for (let x of iter) {
            if (f(x)) yield x;
        }
    }

    function* take(iter, n) {
        let i = 0;
        for (let x of iter) {
            if (i++ < n) yield x;
            else break;
        }
    }

    class IteratorWrapper {
        constructor(iterable) {
            this.iter = iterable[Symbol.iterator]();
        }

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

        map(f) {
            return from(map(this.iter, f));
        }

        filter(f) {
            return from(filter(this.iter, f));
        }

        take(n) {
            return from(take(this.iter, n));
        }

        toArray() {
            return [...this.iter];
        }
    }

    // Voorbeeld gebruik:
    const numbers = [1, 2, 3, 4, 5];
    const result = from(numbers)
        .map(x => x * 2)
        .filter(x => x > 5)
        .take(2)
        .toArray();

    console.log(result); // [6, 8]

})();

Example:

(() => {
    function from(iterable) {
        return new IteratorWrapper(iterable);
    }

    function* map(iter, f) {
        for (let x of iter) {
            yield f(x);
        }
    }

    function* filter(iter, f) {
        for (let x of iter) {
            if (f(x)) yield x;
        }
    }

    function* take(iter, n) {
        let i = 0;
        for (let x of iter) {
            if (i++ < n) yield x;
            else break;
        }
    }

    class IteratorWrapper {
        constructor(iterable) {
            this.iter = iterable[Symbol.iterator]();
        }
        [Symbol.iterator]() {
            return this.iter;
        }
        map(f) {
            return from(map(this.iter, f));
        }
        filter(f) {
            return from(filter(this.iter, f));
        }
        take(n) {
            return from(take(this.iter, n));
        }
        first() {
            return this.iter?.next()?.value || undefined;
        }
        toArray() {
            return [...this.iter];
        }
    }

    const dataStr = ["<div class=\"c-clients__contain\" id=\"jsClientsItemsHolder\">",
        "<a href=\"https://www.2foqus.nl/\" target=\"_BLANK\" class=\"c-clients__item\">",
        "<figure class=\"c-clients__figure\">",
        "\t\t\t\t<img src=\"https://tans.net/storage/1194/conversions/2foqus-2019-Identity-Logo-CMYK-1.2-(002)-logo.png\" alt=\"2Foqus\" class=\"c-clients__img\">",
        "\t\t</figure>",
        "</a>",
        "\t<a href=\"https://www.aartstoiletcabine.nl/\" target=\"_BLANK\" class=\"c-clients__item\">",
        "<figure class=\"c-clients__figure\">",
        "\t\t\t\t<img src=\"https://tans.net/storage/1163/conversions/Aarts-Sanitair-Service-logo.PNG\" alt=\"Aarts Sanitair Service\" class=\"c-clients__img\">",
        "\t\t</figure>",
        "</a>",
        "\t<a href=\"https://www.abrex.nl/\" target=\"_BLANK\" class=\"c-clients__item\">",
        "<figure class=\"c-clients__figure\">",
        "\t\t\t\t<img src=\"https://tans.net/storage/1107/conversions/Logo-Abrex-logo.png\" alt=\"Abrex Logistics B.V.\" class=\"c-clients__img\">",
        "\t\t</figure>",
        "</a>",
        "</div>\t"].join("\n");

    const matches = (source, regex) => from(String(source || "").matchAll(regex));

    const reLinks = /<a\s(.*?)>(.*?)<\/a>/gms;
    const reHref = /href="(.*?)"/gms;
    const reAlt = /<img\s.*?alt="(.*?)".*?>/gms;

    const items = matches(dataStr, reLinks)
        .map(x => {
            const [_, attrs, content] = x;
            return { 
                alt:  matches(content, reAlt).first()[1],
                href: matches(attrs, reHref).first()[1] 
            };
        })
        .take(2)
        .toArray();

    console.log(items);
})();
(() => {
    function createIteratorWrapper(iterable) {
        const iter = iterable[Symbol.iterator](); // Haal de iterator op van het meegegeven iterable object
        return {
            [Symbol.iterator]() {
                return iter;
            },
            map(f) {
                return createIteratorWrapper(function* () { 
                    for (let x of iter) {
                        yield f(x);
                    }
                }());
            },
            filter(predicate) {
                return createIteratorWrapper(function* () {
                    for (let x of iter) {
                        if (predicate(x)) yield x;
                    }
                }());
            },
            take(n) {
                return createIteratorWrapper(function* () {
                    let i = 0;
                    for (let x of iter) {
                        if (i++ < n) yield x;
                        else break;
                    }
                }());
            },
            toArray() {
                return [...iter];
            }
        };
    }
    
    // Voorbeeld gebruik:
    const numbers = [1, 2, 3, 4, 5];
    const iter = createIteratorWrapper(numbers);

    const result = iter
        .map(x => x * 2)
        .filter(x => x > 5)
        .take(2)
        .toArray();

    console.log(result); // [6, 8]
})();
88540cookie-checkJavascript IteratorWrapper