Enhancing Search Logic with JavaScript

Optimizing and Enhancing a Tire Size Search Logic in JavaScript

When building a tire size search feature, efficiency and accuracy are crucial. I recently faced a challenge with a function designed to filter tire sizes based on user input. The input format for tire sizes typically looks like “Width/Depth R Rim”, such as “215/55R15”. In our code, we need to handle cases where the user might enter partial numbers, and we should still retrieve relevant results. For example, when searching by width, if the user inputs “2”, the results should include all tire sizes where the width starts with “2”, like “215” or “220”, but not “320”.

The current implementation involved complex regular expressions and multiple filtering steps, which made me think there might be a more streamlined approach not only to improve performance but also to enhance code readability and maintainability.

Here’s the initial implementation that needs optimization:

function testInput(input, stringToMatch, test_regex) {
    console.log(input, stringToMatch);
    
    if (!test_regex.test(input)) {
        return false;
    }
    
    const regex = new RegExp(`^${input}`);
    return regex.test(stringToMatch);
}

function parseTireSize(tireSize, parse_regex) {
    const matches = tireSize.match(parse_regex);
    if (matches && matches.length === 4) {
        const width = parseInt(matches[1]);
        const depth = parseInt(matches[2]);
        const rim = parseInt(matches[3]);
        return { width, depth, rim };
    } else {
        return null;
    }
}

function SearchLogic({ setData, server_data, searchInput }) {
    const parse_regex = /(\d+)\/(\d+)R(\d+)/;
    const test_regex = /^\d+$/;
    const filteredTireList = server_data.filter((tire) => {
        const { width, depth, rim } = parseTireSize(tire.tire_size, parse_regex);
        const width_test = testInput(searchInput.width, width, test_regex);
        const depth_test = testInput(searchInput.depth, depth, test_regex);
        const rim_test = testInput(searchInput.rim, rim, test_regex);
        return width_test && depth_test && rim_test;
    });

    setData(filteredTireList)
}

Simplifying and Streamlining the Process

First, let’s tackle the testInput function. Given its role, this function can easily become a bottleneck due to the repeated creation of regular expression objects inside a loop—especially with large datasets. We can simplify this function by directly using string operations, which are generally faster than regular expressions for simple prefix checks.

Here’s how I would refactor testInput:

function isPrefixMatch(input, numberToMatch) {
    return numberToMatch.toString().startsWith(input.toString());
}

Next, we look at the parseTireSize function. While using a regular expression here makes sense due to the complex parsing requirements of the tire size string, we can improve error handling and reduce overhead by caching the regular expression outside of the function to avoid recompilation:

const tireSizeRegex = /(\d+)\/(\d+)R(\d+)/;

function parseTireSize(tireSize) {
    const matches = tireSize.match(tireSizeRegex);
    return matches ? { width: parseInt(matches[1]), depth: parseInt(matches[2]), rim: parseInt(matches[3]) } : null;
}

Finally, in SearchLogic, we can use these improved functions to speed up our filtering logic:

function SearchLogic({ setData, server_data, searchInput }) {
    const filteredTireList = server_data.filter(tireDetails => {
        const parsedTire = parseTireSize(tireDetails.tire_size);
        if (!parsedTire) return false;
        
        return (!searchInput.width || isPrefixMatch(searchInput.width, parsedTire.width)) &&
               (!searchInput.depth || isPrefixMatch(searchInput.depth, parsedTire.depth)) &&
               (!searchInput.rim || isPrefixMatch(searchInput.rim, parsedTire.rim));
    });

    setData(filteredTireList);
}

By focusing on simplifying test inputs and leveraging efficient string methods over heavier regular expression logic, we’ve made the code more manageable and potentially boosted its execution speed. This approach also makes the functions easier to test and maintain, which is an essential aspect of software development.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *