0

I am trying to create an array from a string input with some conditions. It doesn't seem like this a valid way to use push, as it's not return an array of just numbers.

    function evaluate(input){ 
        function isOperator(ops){
            if(ops == '+' || ops == '*'){
                return true;
            } return false;
        }
        var stack = [];
        for(var char in input){
            if(!isOperator(char)){
                stack.push(input[char]);
            }
        } 
        return stack;
    }
    console.log(evaluate('7+**8'));
Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
bsem
  • 175
  • 1
  • 2
  • 12

5 Answers5

2

This line is testing whether the index is an operator. It's not because indexes are always numbers.

if(!isOperator( char )){   // char => 0, 1, 2, 3, 4
//              ^^^^

While the next line uses the index to access the individual character from the input string:

stack.push( input[char] ); // input[char] => '7', '+', '*', '*', '8'
//          ^^^^^^^^^^^

This would be a good time to rename the variable to avoid the confusion.

for (var index in input) {
    var char = input[index];
    if (!isOperator(char)) {
        stack.push(char);
    }
}

Also, changing the type of loop to one more suited for ordered collections.

Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
2

There's a number of issues with your code.

for(var char in input) doesn't do what you want. It iterates over it like an object. Use for (var i = 0; i < input.length; i++). It wouldn't be as efficient, but you could also do input.split().reduce(...).

input[char] will result in undefined since input['c'] or the like won't exist. However, switching to i as the index will fix that.

function evaluate(input){ 
    function isOperator(ops){
        if(ops == '+' || ops == '*'){
            return true;
        }
        return false;
    }
    var stack = [];
    for(var i = 0; i < input.length; i++){
        var char = input[i];
        if(!isOperator(char)){
            stack.push(char);
        }
    } 
    return stack;
}
console.log(evaluate('7+**8'));

Or, with reduce:

return input.split().reduce(function (stack, value) {
    if (isOperator(value)) {
        return stack;
    }
    return stack.concat(value);
}, []);
EmptyArsenal
  • 7,314
  • 4
  • 33
  • 56
0
function evaluate(input){ 
    function isOperator(ops){
        if(ops == '+' || ops == '*'){
            return true;
        } return false;
    }
    var stack = [];
    for(var char in input){
        if(!isOperator(char)){
            stack.push(input[char]);
        }
    } 
    return stack;
}
console.log(evaluate('7+**8'));

This should work assuming you're trying to do what I think. You cant do an associative array like that in JS but other than that it looks fine. Make sure you know what variables you're calling.

  • "*This should work…*"? An answer should explain why the OP has their issue and how your code fixes it. – RobG Sep 09 '17 at 01:45
0

You are not even checking whether the inputs are "+" or "*". You are simply returning false from the isOperator(ops) method because your for loop is just counting the input values index from evaluate(input) method. So you need to fix it so it checks the "+" and "*" operators.

eyoeldefare
  • 2,136
  • 1
  • 15
  • 25
0

Is this the output you want?

[
  "7",
  "8"
]

If so, others have ably explained the issues with the syntax: for key in obj iterates over objects, not arrays. You could use a regular for loop if you want to iterate the string as an array in the "traditional" way:

function evaluate(input) {
  var output = [];
  for (var n = 0; n < input.length; n++) {
    if (! (input[n] === '*' || input[n] === '+'))  output.push(input[n]);
  }
  return output;
}
console.log(evaluate('7+**8'));

But you don't have to. If you just want all numbers and no operators, then this might win the code golf challenge:

function evaluate(input) {
  return input.match(/\d/g); 
}
console.log(evaluate('7+**8'));
globewalldesk
  • 544
  • 1
  • 3
  • 18