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

dadadodo
  • 349
  • 2
  • 15
  • so the result should be a string, or the value 16 (or zero if you take into consideration operator precedence) – Jaromanda X Nov 09 '16 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. – T.J. Crowder Nov 09 '16 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) – dadadodo Nov 09 '16 at 10:26

5 Answers5

1

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

finalArr = [12,'+',4,'-',8,'*',2];
Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156
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]));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

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

finalArr = [12, '+', 4, '-', 8, '*', 2];
console.log(
  eval(finalArr.join(''))
)
Community
  • 1
  • 1
maioman
  • 18,154
  • 4
  • 36
  • 42
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 ;)

j_freyre
  • 4,623
  • 2
  • 30
  • 47
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
S Vinesh
  • 529
  • 1
  • 4
  • 15