0

I have this array finalArr = [12,+,4,-,8,*,2]; I want to reduce the array to a single value like so: var result = 12+4-8*2;

here is what I have done:

var operators = {'+' : function (a,b) {return a + b},
                 '-' : function (a,b){return a - b},
                 '*' : function (a,b){return a * b},
                 '/' : function (a,b){return a / b}};

var opSymbols = ['+','-','*','/'];
finalArr = [12,+,4,-,8,*,2];
finalArr.reduce(function (acc,next,index,arr){
        for (var m = 0; m < opSymbols.length; m++) {
            var op = '';
            if (opSymbols[m] === arr[1]) {
                op = opSymbols[m];
                acc = operators[op](arr[0],arr[2]);
            }
            if (index > 1 && opSymbols[m] === arr[index]) {
                op = opSymbols[m];
                acc +=  arr[index+1];
            }
        }

        return  acc;
    });

I'm getting a syntax error in the finalArr.reduce line (SyntaxError: expected expression, got ',') and I don't think I'm executing the reduce method correctly. any help? thanks

3
  • so the result should be a string, or the value 16 (or zero if you take into consideration operator precedence) Commented Nov 9, 2016 at 10:12
  • Note that with Robby's fix, you'll get the result 16; mathematically, though, things are more complicated because of the order of operations. The mathematic result should be 0, because 12 + 4 - 8 * 2 is (12 + 4) - (8 * 2), not (12 + 4 - 8) * 2. Commented Nov 9, 2016 at 10:12
  • @T.J.Crowder this is suppose to be part of a calculator program so a+b*c shoud be c*(a+b) Commented Nov 9, 2016 at 10:26

5 Answers 5

1

The operators are strings, so you need to quote them:

finalArr = [12,'+',4,'-',8,'*',2];
Sign up to request clarification or add additional context in comments.

Comments

1

A solution without reduce and eval, but with operator precedence.

function calculate(a) {
    while (a.length > 1) {
        precedence.some(function (b) {
            return a.some(function (c, i) {
                if (b === c) {
                    return operators[b](a, i);
                }
            });
        });
    }
    return a[0];
}

var operators = {
        '+': function (a, i) {
            a[i - 1] += a.splice(i, 2)[1];
            return true;
        },
        '-': function (a, i) {
            a[i - 1] -= a.splice(i, 2)[1];
            return true;
        },
        '*': function (a, i) {
            a[i - 1] *= a.splice(i, 2)[1];
            return true;
        },
        '(': function (a, i) {
            var j = i + 1, b;
            while (j < a.length) {
                if (a[j] === ')') {
                    b = a.splice(i + 1, j - i);
                    b.pop();
                    a[i] = calculate(b);
                    return true;
                }
                if (a[j] === '(') {
                    return false;
                }
                j++;
            }
        },
        ')': 0
    },
    precedence = ['(', '*', '+', '-'];

console.log(calculate([12, '+', 4, '-', 8, '*', 2]));
console.log(calculate([7, '*', 8, '-', 3.5, '*', 4]));

Comments

0

Eval is evil,
but if you want to test it:

finalArr = [12, '+', 4, '-', 8, '*', 2];
console.log(
  eval(finalArr.join(''))
)

Comments

0

In case your array is an array of mixed string/int like

var finalArr = [12,'+',4,'-',8,'*',2];

You can generate the expected result by the following command

var result = finalArr.join('');

and if you need to calculate the result

var final = eval(result);

Hope it'll help you ;)

Comments

0

If you really want to do with reduce and not to use eval

var opSymbols = ['+','-','*','/'];
var finalArr = [12,'+',4,'-',8,'*',2];
var result = finalArr.reduce(function (previousValue,currentValue,currentIndex,array){
    var res;
    var opr;
    if(typeof currentValue == 'number') {
            switch(previousValue.operator){
                case '+':
                    res = previousValue.value + currentValue;break;
                case '-':
                    res = previousValue.value - currentValue;break;
                case '*':
                    res = previousValue.value * currentValue; break;
                case '/':
                    res = previousValue.value / currentValue; break;
            }
            opr = previousValue.operator;
    }

    else if(typeof currentValue == 'string') {
        res = previousValue.value;
        opr = currentValue;
    }

    return {'value':res,'operator': opr};



},{'value':0,'operator':'+'});

console.log(result.value); // this gives 16

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.