Capture groups

Benchmark created on


Setup

function getRouteRe(segments) {
    const segmentsMatcher = segments.join('|');

    /**
     * матчер может вызваться как на pathname, который начинается со /, так и на Page,
     * поэтому нужно поддержать оба варианта
    */
    return new RegExp(`^\/?${
        segments.length > 1 ? `(${segmentsMatcher})` : segmentsMatcher
    }`);
}

function createCapturingRe(source) {
    const groups = [];

    for (const [page, segments] of source) {
        if (page && segments) groups.push(`(?<${page}>${segments.join('|')})`);
    }

    return getRouteRe(groups);
}

function getMatchedPage(capturingRe, pathname) {
    const groups = capturingRe.exec(pathname)?.groups;

    if (!groups) return;

    const nonEmptyGroups = (Object.keys(groups))
        .filter(key => groups[key]);

    return nonEmptyGroups[0];
}

const PATHNAME_SEGMENTS_OF_PAGE = new Map([
    ['maps', ['maps']],
    ['pollution', ['pollution', 'frame']],
    ['details', ['details']],
    ['blog', ['blog']],
    ['search', ['search']],
    ['region', ['region']],
    ['month', ['month']],
    ['sources', ['sources']],
    ['history', ['history']],
    ['event', ['event']],
    ['date', ['date']],
]);

const getPageCapturing = (PATHNAME_SEGMENTS_OF_PAGE => {
    const capturingRe = createCapturingRe(PATHNAME_SEGMENTS_OF_PAGE);
    const DEFAULT_PAGE = 'main';

    return (pathname) => {
        return getMatchedPage(capturingRe, pathname) ?? DEFAULT_PAGE;
    };
})(PATHNAME_SEGMENTS_OF_PAGE);

//////

const ROUTE_OR_PAGE_REGEXPS = new Map([
    ['maps', getRouteRe(['maps'])],
    ['pollution', getRouteRe(['pollution', 'frame'])],
    ['details', getRouteRe(['details'])],
    ['blog', getRouteRe(['blog'])],
    ['search', getRouteRe(['search'])],
    ['region', getRouteRe(['region'])],
    ['month', getRouteRe(['month'])],
    ['sources', getRouteRe(['sources'])],
    ['history', getRouteRe(['history'])],
    ['event', getRouteRe(['event'])],
    ['date', getRouteRe(['date'])],
]);

const getPage = (pathname) => {
    for (const [page, matcher] of ROUTE_OR_PAGE_REGEXPS) {
        if (matcher.test(pathname)) {
            return page;
        }
    }

    return 'main';
};

////////
const ROUTE_REGEXPS = new Map([
    ['maps', /^\/?maps/],
    ['pollution', /^\/?(pollution|frame)/],
    ['details', /^\/?details/],
    ['blog', /^\/?blog/],
    ['search', /^\/search/],
    ['region', /^\/region/],
    ['month', /^\/month/],
    ['sources', /^\/sources/],
    ['history', /^\/?history/],
    ['event', /^\/?event/],
    ['date', /^\/?date/],
]);

const getPageByIf = (pathname) => {
    if (ROUTE_REGEXPS.get('maps')?.test(pathname)) {
        return 'maps';
    }
    if (ROUTE_REGEXPS.get('pollution')?.test(pathname)) {
        return 'pollution';
    }
    if (ROUTE_REGEXPS.get('details')?.test(pathname)) {
        return 'details';
    }
    if (ROUTE_REGEXPS.get('blog')?.test(pathname)) {
        return 'blog';
    }
    if (ROUTE_REGEXPS.get('search')?.test(pathname)) {
        return 'search';
    }
    if (ROUTE_REGEXPS.get('region')?.test(pathname)) {
        return 'region';
    }
    if (ROUTE_REGEXPS.get('month')?.test(pathname)) {
        return 'month';
    }
    if (ROUTE_REGEXPS.get('sources')?.test(pathname)) {
        return 'sources';
    }
    if (ROUTE_REGEXPS.get('history')?.test(pathname)) {
        return 'history';
    }
    if (ROUTE_REGEXPS.get('event')?.test(pathname)) {
        return 'event';
    }
    if (ROUTE_REGEXPS.get('date')?.test(pathname)) {
        return 'date';
    }

    return 'main';
};

Test runner

Ready to run.

Testing in
TestOps/sec
Capturing group
getPageCapturing('date')
ready
Separate matchers
getPage('date')
ready
IF else
getPageByIf('date')
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.