2

I am working with JS and have a problem where I have two strings such as:

var test = "This is a {feature1} and {feature2} boy.";
var data = "This is a very good and smart boy.";

Considering whatever word is wrapped in {} is a variable, substituting the appropriate value of the variables will convert test to data.

The problem statement is we need to find the values of every word in case if the problem has a solution, otherwise, return false from the method.

So, in the above example, we have a return value as

{
    feature1: 'very good',
    feature2: 'smart'
}

So far, I have tried the below code which seems to be working though, but it seems a bit complex for this operation.

function matchAndGetVar(test, data) {
    function multiSplit(data, splitters) {
        function helper(dataArray, splitter) {
            return dataArray.reduce((acc, curr) => {
                acc.push(...curr.split(splitter));
                return acc;
            }, []);
        }
    
        return splitters.reduce((acc, curr) => helper(acc, curr), [data]).map((f, index) => {
            if (index % 2 === 0) return f;
            return '{' + f + '}';
        });
    }

    var splittedTestData = multiSplit(test, ['{', '}']);
    
    return splittedTestData.reduce((acc, curr, index) => {
        if (curr.startsWith("{") && curr.endsWith("}")) {}
        else if (index === 0) {
            if (data.startsWith(curr)) {
                data = data.substr(curr.length);
            } else {
                return false;
            }
        } else if (splittedTestData[index] === "") {
            if (acc)
                acc[splittedTestData[index - 1].substr(1, splittedTestData[index - 1].length - 2)] = data;
            data = "";
        } else {
            const index1 = data.indexOf(splittedTestData[index]);
            if (index1 === -1) return false;
            if (acc)
                acc[splittedTestData[index - 1].substr(1, splittedTestData[index - 1].length - 2)] = data.substr(0, index1);
            data = data.substr(index1 + splittedTestData[index].length);
        }
        return acc;
    }, {});
}

var test = "This is a {feature1} and {feature2} boy.";
var data = "This is a very good and smart boy.";

console.log(matchAndGetVar(test, data));

Can anyone suggest something simpler approach or any modification to the implementation?

2
  • functions inside functions inside functions inside functions ... Commented Jan 7, 2020 at 17:59
  • also helper means nothing. Every function is a helper. Name your functions with verbs that represent what they do. Commented Jan 7, 2020 at 18:00

1 Answer 1

5

You can use the regex, there is an example

var test = "This is a {feature1} and {feature2} boy.";
var data = "This is a very good and smart boy.";

let resp = findFeatures(test);
console.log(resp)
function findFeatures(data) {

    let features = {};

    /* EXTRACTING FEATURE KEYS */
    data.match(/\{(.+?)\}/g).forEach(result => {
        features[result.slice(1, -1)] = ""
    })

    let matches = matchWithData(test);
    if (Object.keys(features).length > 0 && matches.length == Object.keys(features).length) { // if pattern results matches with data
        Object.keys(features).forEach((feature, index) => {
            features[feature] = matches[index]
        })
    }
    return features;
}

function matchWithData(test) {

    let regex = test.replace(/\{.+?\}/g, "(.*)");

    if (new RegExp(regex).test(data)) // data matches with test
        return data.match(new RegExp(regex)).slice(1); // get features
    return [];
}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.