Как я анализирую и оцениваю математическое выражение в строке (например. '1+1'
) без вызова eval(string)
привести к его численному значению?
С тем примером я хочу, чтобы функция приняла '1+1'
и возвратитесь 2
.
const getAddition = (str) => {
return str.split('+').reduce((total, num) => (total + num * 1), 0);
};
const addition = getAddition('1+1');
дополнение равняется 2.
Вот алгоритмическое решение, подобное 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);
}
Я полагаю, что 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
синтаксические анализы число с оператором. Код может быть изменен к соответствующим потребностям.
Попробуйте AutoCalculator https://, github.com/JavscriptLab/autocalculate Вычисляет значение Исходных данных, и Вывод При помощи селекторных выражений
Просто добавляют атрибут для Вашего выходного входа как данные-ac = "(#firstinput +#secondinput)",
, Никакая Потребность любой инициализации просто не добавляет, что данные-ac приписывают только. Это узнает, что динамично добавленные элементы автоматически
ДЛЯ добавляют, что 'RS' с Выводом просто добавляет внутренние данные-ac фигурной скобки = "{RS} (#firstinput +#secondinput)"
Альтернатива превосходному ответу @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);
});
}
Попробуйте 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>
Я создал 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 для арифметики в случае, если Вы имеете дело с числами с произвольной точностью.
Я пошел, ища библиотеки JavaScript для оценки математических выражений и нашел эти двух многообещающих кандидатов:
Средство анализа выражения JavaScript : Меньший и надо надеяться более легкий. Позволяет алгебраические выражения, замены и много функций.
mathjs: Позволяет комплексные числа, матрицы и единицы также. Созданный, чтобы использоваться и JavaScript в браузере и Node.js.
Можно использовать библиотека Evaluator выражения JavaScript , который позволяет Вам делать материал как:
Parser.evaluate("2 ^ x", { x: 3 });
Или mathjs, который позволяет материал как:
math.eval('sin(45 deg) ^ 2');
я закончил тем, что выбрал mathjs для одного из моих проектов.
Это - немного функции, которую я бросил вместе сейчас для решения этой проблемы - она создает выражение путем анализа строки один символ за один раз (это на самом деле довольно быстро хотя). Это возьмет любое математическое выражение (ограниченный +, - *, / только операторы) и возвратит результат. Это может обработать отрицательные величины и операции неограниченного количества также.
единственное, "чтобы сделать" оставленный должно удостовериться, что вычисляет * & / прежде + &-. Добавит, что функциональность позже, но на данный момент это делает то, в чем я нуждаюсь...
/**
* 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;
}