Оценка строки как математическое выражение в JavaScript

Как я анализирую и оцениваю математическое выражение в строке (например. '1+1') без вызова eval(string) привести к его численному значению?

С тем примером я хочу, чтобы функция приняла '1+1' и возвратитесь 2.

62
задан 4 February 2013 в 14:51

10 ответов

const getAddition = (str) => {
  return str.split('+').reduce((total, num) => (total + num * 1), 0);
};

const addition = getAddition('1+1');

дополнение равняется 2.

0
ответ дан 31 October 2019 в 13:42

Вот алгоритмическое решение, подобное jMichael's, что циклы через символ выражения символом и прогрессивно отслеживают левый/оператор/право. Функция накапливает результат после каждого поворота, это находит символ оператора. Эта версия только поддерживает '+' и '-' операторы, но записана, чтобы быть расширенной с помощью других операторов.Примечание: мы устанавливаем 'currOp' на '+' перед цикличным выполнением, потому что мы предполагаем, что выражение запускается с положительного плавания. На самом деле в целом я делаю предположение, которые вводят, подобно тому, что прибыло бы из калькулятора.

function calculate(exp) {
  const opMap = {
    '+': (a, b) => { return parseFloat(a) + parseFloat(b) },
    '-': (a, b) => { return parseFloat(a) - parseFloat(b) },
  };
  const opList = Object.keys(opMap);

  let acc = 0;
  let next = '';
  let currOp = '+';

  for (let char of exp) {
    if (opList.includes(char)) {
      acc = opMap[currOp](acc, next);
      currOp = char;
      next = '';
    } else {
      next += char;
    } 
  }

  return currOp === '+' ? acc + parseFloat(next) : acc - parseFloat(next);
}
0
ответ дан 31 October 2019 в 13:42

Я полагаю, что parseInt и ES6 может быть полезным в этой ситуации

==> таким образом:

let func = (str) => {
let arr = str.split("");
return `${Number(arr[0]) + parseInt(arr[1] + Number(arr[2]))}`};
console.log(func("1+1"));

главное здесь состоит в том что parseInt синтаксические анализы число с оператором. Код может быть изменен к соответствующим потребностям.

1
ответ дан 31 October 2019 в 13:42

Попробуйте AutoCalculator https://, github.com/JavscriptLab/autocalculate Вычисляет значение Исходных данных, и Вывод При помощи селекторных выражений

Просто добавляют атрибут для Вашего выходного входа как данные-ac = "(#firstinput +#secondinput)",

, Никакая Потребность любой инициализации просто не добавляет, что данные-ac приписывают только. Это узнает, что динамично добавленные элементы автоматически

ДЛЯ добавляют, что 'RS' с Выводом просто добавляет внутренние данные-ac фигурной скобки = "{RS} (#firstinput +#secondinput)"

1
ответ дан 31 October 2019 в 13:42

Альтернатива превосходному ответу @kennebec, с помощью более короткого регулярного выражения и позволяя пробелы между операторами

function addbits(s) {
    var total = 0;
    s = s.replace(/\s/g, '').match(/[+\-]?([0-9\.\s]+)/g) || [];
    while(s.length) total += parseFloat(s.shift());
    return total;
}

Использование это как

addbits('5 + 30 - 25.1 + 11');

Обновление

Вот является более оптимизированной версией

function addbits(s) {
    return (s.replace(/\s/g, '').match(/[+\-]?([0-9\.]+)/g) || [])
        .reduce(function(sum, value) {
            return parseFloat(sum) + parseFloat(value);
        });
}
8
ответ дан 31 October 2019 в 13:42

Попробуйте nerdamer

var result = nerdamer('12+2+PI').evaluate();
document.getElementById('text').innerHTML = result.text();
<script src="http://nerdamer.com/js/nerdamer.core.js"></script>
<div id="text"></div>
2
ответ дан 31 October 2019 в 13:42

Я создал BigEval для той же цели.
В решении выражений, это выполняет точно то же как Eval() и поддерживает операторы как %, ^, & ** (питание) и! (факториал). Вам также разрешают использовать функции и константы (или сказать переменные) в выражении. Выражение решено в порядок PEMDAS, который распространен в языках программирования включая JavaScript.

var Obj = new BigEval();
var result = Obj.exec("5! + 6.6e3 * (PI + E)"); // 38795.17158152233
var result2 = Obj.exec("sin(45 * deg)**2 + cos(pi / 4)**2"); // 1
var result3 = Obj.exec("0 & -7 ^ -7 - 0%1 + 6%2"); //-7

Это может также быть сделано пользоваться теми библиотеками Big Number для арифметики в случае, если Вы имеете дело с числами с произвольной точностью.

9
ответ дан 31 October 2019 в 13:42

Я пошел, ища библиотеки JavaScript для оценки математических выражений и нашел эти двух многообещающих кандидатов:

  • Средство анализа выражения JavaScript : Меньший и надо надеяться более легкий. Позволяет алгебраические выражения, замены и много функций.

  • mathjs: Позволяет комплексные числа, матрицы и единицы также. Созданный, чтобы использоваться и JavaScript в браузере и Node.js.

7
ответ дан 31 October 2019 в 13:42

Можно использовать библиотека Evaluator выражения JavaScript , который позволяет Вам делать материал как:

Parser.evaluate("2 ^ x", { x: 3 });

Или mathjs, который позволяет материал как:

math.eval('sin(45 deg) ^ 2');

я закончил тем, что выбрал mathjs для одного из моих проектов.

57
ответ дан 31 October 2019 в 13:42

Это - немного функции, которую я бросил вместе сейчас для решения этой проблемы - она создает выражение путем анализа строки один символ за один раз (это на самом деле довольно быстро хотя). Это возьмет любое математическое выражение (ограниченный +, - *, / только операторы) и возвратит результат. Это может обработать отрицательные величины и операции неограниченного количества также.

единственное, "чтобы сделать" оставленный должно удостовериться, что вычисляет * & / прежде + &-. Добавит, что функциональность позже, но на данный момент это делает то, в чем я нуждаюсь...

/**
* Evaluate a mathematical expression (as a string) and return the result
* @param {String} expr A mathematical expression
* @returns {Decimal} Result of the mathematical expression
* @example
*    // Returns -81.4600
*    expr("10.04+9.5-1+-100");
*/ 
function expr (expr) {

    var chars = expr.split("");
    var n = [], op = [], index = 0, oplast = true;

    n[index] = "";

    // Parse the expression
    for (var c = 0; c < chars.length; c++) {

        if (isNaN(parseInt(chars[c])) && chars[c] !== "." && !oplast) {
            op[index] = chars[c];
            index++;
            n[index] = "";
            oplast = true;
        } else {
            n[index] += chars[c];
            oplast = false;
        }
    }

    // Calculate the expression
    expr = parseFloat(n[0]);
    for (var o = 0; o < op.length; o++) {
        var num = parseFloat(n[o + 1]);
        switch (op[o]) {
            case "+":
                expr = expr + num;
                break;
            case "-":
                expr = expr - num;
                break;
            case "*":
                expr = expr * num;
                break;
            case "/":
                expr = expr / num;
                break;
        }
    }

    return expr;
}
4
ответ дан 31 October 2019 в 13:42

Другие вопросы по тегам:

Похожие вопросы: