2013-04-27 3 views
0

Просто сказать, у меня есть строка, как это: «1 + 2 + 3 * 4»Обойти оператор старшинства в JavaScript

Можно ли вычислить его слева направо, так что она равна (последовательно Линейно?) 24 и не 15?

Я не знаю, что строка, прежде чем руки, так что он может быть '1 + 2', или это может быть '1 + 7 * 11 - 18/32 * 155'

+3

..why нет скобка? '(1 + 2 + 3) * 4' –

+0

Ну, это было первое, что я, конечно же, подумал, но, как правильно разместить их? Что, если это второй пример строки, и мне нужно больше 1 набора круглых скобок? – danwellman

+0

Проверка разбора деревьев: http://stackoverflow.com/questions/2705727/generate-syntax-tree-for-simple-math-operations –

ответ

1

Предполагая, что вы начинаете с числом и пространств только (и всегда) происходят между числами и операторами, можно разделить строку и передать его через объект определенных операторов

var num_eval = (function() { 
    var ops = { 
     '+': function (x, y) {return x + y}, 
     '-': function (x, y) {return x - y}, 
     '*': function (x, y) {return x * y}, 
     '/': function (x, y) {return x/y} 
     // etc.. 
    }; 
    return function (str_command) { 
      var str_arr = str_command.split(' '), 
       lhs = +str_arr[0], i = 1; // + to cast Number 
      for (; i < str_arr.length; i = i + 2) { 
       lhs = ops[str_arr[i]](lhs, +str_arr[i+1]); // + to cast Number 
      } 
      return lhs; 
     }; 
    }()); 

num_eval('1 + 2 + 3 * 4'); // 24 
num_eval('1 + 7 * 11 - 18/32 * 155'); // 339.0625 

Если вы хотите быть немного более расслабленным о форматировании строки, то вы можете использовать следующую RegExp.

str_arr = str_command.match(/([\+\-\*\/]|[\d]*[\.e]?[\d]+)/g) 

Петля все еще принимает массив нечетной длины, начиная с номера (в виде строки).

+0

ahh, это выглядит многообещающим :) тестирование сейчас ... – danwellman

+0

Чтобы немного расслабиться, вы можете использовать _RegExp_ вместо '.split', например '/ ([\ + \ - \ * \ /] | [\ d] * \.? [\ d] +)/g' –

+0

Ну, я уже использую regex, чтобы обрезать любые трейлинг-операторы, но спасибо. Все еще реализуя это ... – danwellman

0

Обычно вы просто вставить скобки.

Но если по какой-то причине вы не можете этого сделать, вы можете разделить строку операторами и затем оценить previous_part + next_part для каждого из них.

Вот супер простой пример:

var string_to_calculate = '1 + 2 + 3 * 4' 
var parts = string_to_calculate.split(' '); 
var result = parts[0]; 

for (var i = 1; i < parts.length - 1; i += 2) { 
    result = eval(result + parts[i] + parts[i + 1]); 
} 

alert(result); 
1

Однострочные:

result = str.match(/\D*\d+/g).reduce(function(r, e) { return eval(r + e) }) 
+0

Это выглядит очень, очень многообещающе, однако, я не смог интегрироваться с моим выходным (и необходимым) кодом. Определенно будет изучать это дальше, спасибо :) – danwellman