skip to Main Content

I have a little calculator app.

The return statement is inside of an if statement checking for a variable to be equal to "null". If the variable is equal to "null", it should return the input the function is called with. However, it always returns undefined, no matter what the input is.

Here is the code:

const input = ['1', 'substract', '3'];

const findNextOperation = (input) => {
    let operation;
    let ind;

    //First * or /
    ind = input.findIndex(el => /multiply|divide/.test(el));

    //Then + or -
    if (ind === -1) ind = input.findIndex(el => /add|substract/.test(el));

    //No operations left
    if (ind === -1) return null;

    operation = input[ind];
    return { operation, ind };
}

const performOperation = (a, b, operation) => {
    a = Number(a);
    b = Number(b);

    switch (operation) {
        case 'add':
            return a + b;
        case 'substract':
            return a - b;
        case 'multiply':
            return a * b;
        case 'divide':
            return a / b;
        default:
            return;
    }
}

const calculate = (input) => {
    const operation = findNextOperation(input);
    if (operation === null) {
        console.log('here', input[0]) // Logs "here -2" to the console
        return input[0]; // Returns "undefined"
    }

    const operationOutcome = performOperation(input[operation.ind - 1], input[operation.ind + 1], operation.operation);
    calculate(input.toSpliced(operation.ind - 1, 3, operationOutcome));
}

console.log(calculate(input)); // Logs "undefined" to the console

I can’t figure out where it goes wrong.

Edit: I didn’t know that was a thing with recursive functions. mb

2

Answers


  1. You’ve made a recursive approach by calling calculate in the calculate function.

    However, the return value of the second call is lost.

    You should change the following

    calculate(input.toSpliced(...
    
    // to
    
    return calculate(input.toSpliced(...
    
    const findNextOperation = (input) => {
        let operation;
        let ind;
    
        //First * or /
        ind = input.findIndex(el => /multiply|divide/.test(el));
    
        //Then + or -
        if (ind === -1) ind = input.findIndex(el => /add|substract/.test(el));
    
        //No operations left
        if (ind === -1) return null;
    
        operation = input[ind];
        return { operation, ind };
    }
    
    const performOperation = (a, b, operation) => {
        a = Number(a);
        b = Number(b);
    
        switch (operation) {
            case 'add':
                return a + b;
            case 'substract':
                return a - b;
            case 'multiply':
                return a * b;
            case 'divide':
                return a / b;
            default:
                return;
        }
    }
    
    const calculate = (input) => {
        const operation = findNextOperation(input);
        if (operation === null) {
            return input[0]; // Returns "undefined"
        }
    
        const operationOutcome = performOperation(input[operation.ind - 1], input[operation.ind + 1], operation.operation);
        return calculate(input.toSpliced(operation.ind - 1, 3, operationOutcome));
    }
    
    console.log(calculate(['1', 'substract', '3']));
    console.log(calculate(['10', 'divide', '3']));
    Login or Signup to reply.
  2. The primary reason you’re getting an "undefined" result from your calculate function is that you’re not returning any value from all possible code paths in the function. Specifically, after the line:

    calculate(input.toSpliced(operation.ind - 1, 3, operationOutcome));
    

    You’re not returning the result of the recursive call to calculate.

    However, there are a few more issues:

    You have a typo in your code. JavaScript arrays have a method named splice not toSpliced. But splice directly modifies the array and returns the removed elements, which isn’t what you want. Instead, you could create a custom method to achieve what you want, or handle the splicing differently.

    When calling splice on an array, you’ll want to be sure that you are removing the correct elements and then inserting the result in their place.

    If you want the calculate function to continue recursively and then eventually return a value once it reaches the base case, you’ll need to ensure you return the result of the recursive call.

    With those things in mind, here’s a revised version of your code:

    const input = ['1', 'substract', '3'];
    
    const findNextOperation = (input) => {
        let operation;
        let ind;
    
        //First * or /
        ind = input.findIndex(el => /multiply|divide/.test(el));
    
        //Then + or -
        if (ind === -1) ind = input.findIndex(el => /add|substract/.test(el));
    
        //No operations left
        if (ind === -1) return null;
    
        operation = input[ind];
        return { operation, ind };
    }
    
    const performOperation = (a, b, operation) => {
        a = Number(a);
        b = Number(b);
    
        switch (operation) {
            case 'add':
                return a + b;
            case 'substract':
                return a - b;
            case 'multiply':
                return a * b;
            case 'divide':
                return a / b;
            default:
                return;
        }
    }
    
    const calculate = (input) => {
        const operation = findNextOperation(input);
        if (operation === null) {
            return input[0];
        }
    
        const operationOutcome = performOperation(input[operation.ind - 1], input[operation.ind + 1], operation.operation);
        const newInput = [...input];
        newInput.splice(operation.ind - 1, 3, operationOutcome);
        return calculate(newInput);
    }
    
    console.log(calculate(input));
    

    This code will now correctly return "-2" for the provided input.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search