Add support for NumVariable expressions such as 2x fixes #6
This commit is contained in:
parent
2b3c06c413
commit
c6973847aa
@ -18,8 +18,10 @@ console.log(Equation.solve('4 * lg(4) ^ 3')); // 32
|
||||
|
||||
// equation
|
||||
let sphereArea = Equation.equation('4 * PI * r^2');
|
||||
|
||||
console.log(sphereArea(5)); // 314.1592653589793
|
||||
|
||||
let test = Equation.equation('2x + 6y');
|
||||
console.log(test(4, 3)).to.equal(8 + 18);
|
||||
```
|
||||
|
||||
You can also register your own operators and constants.
|
||||
|
59
dist/index.js
vendored
59
dist/index.js
vendored
@ -70,14 +70,14 @@ var Equation = {
|
||||
*/
|
||||
equation: function equation(expression) {
|
||||
var stack = parseExpression(expression);
|
||||
console.log(stack);
|
||||
var variables = [];
|
||||
|
||||
stack.forEach(function varCheck(a) {
|
||||
if (Array.isArray(a)) {
|
||||
return a.forEach(varCheck);
|
||||
}
|
||||
|
||||
if (typeof a === 'string' && !_.isNumber(a) && !_operators2['default'][a] && a === a.toLowerCase()) {
|
||||
if (isVariable(a)) {
|
||||
// grouped variables like (y) need to have their parantheses removed
|
||||
variables.push(_.removeSymbols(a));
|
||||
}
|
||||
@ -88,15 +88,30 @@ var Equation = {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
expression = expression.replace(/[a-z]*/g, function (a) {
|
||||
stack.forEach(function varCheck(a, i, arr) {
|
||||
if (Array.isArray(a)) {
|
||||
return a.forEach(varCheck);
|
||||
}
|
||||
|
||||
var index = variables.indexOf(a);
|
||||
if (index > -1) {
|
||||
return args[index] || 0;
|
||||
// grouped variables like (y) need to have their parantheses removed
|
||||
arr[i] = args[index];
|
||||
}
|
||||
return a;
|
||||
});
|
||||
|
||||
return Equation.solve(expression);
|
||||
stack = sortStack(stack);
|
||||
stack = _.parseNumbers(stack);
|
||||
stack = solveStack(stack);
|
||||
// expression = expression.replace(/[a-z]*/g, a => {
|
||||
// let index = variables.indexOf(a);
|
||||
// if (index > -1) {
|
||||
// return args[index] || 0;
|
||||
// }
|
||||
// return a;
|
||||
// });
|
||||
|
||||
return stack;
|
||||
};
|
||||
},
|
||||
|
||||
@ -154,12 +169,15 @@ var MIN_PRECEDENCE = Math.min.apply(Math, _toConsumableArray(PRECEDENCES));
|
||||
var parseExpression = function parseExpression(expression) {
|
||||
var stream = new _ReadStream2['default'](expression),
|
||||
stack = [],
|
||||
record = '';
|
||||
record = '',
|
||||
cur = undefined,
|
||||
past = undefined;
|
||||
|
||||
// Create an array of separated numbers & operators
|
||||
while (stream.next()) {
|
||||
var cur = stream.current(),
|
||||
past = stack.length - 1;
|
||||
cur = stream.current();
|
||||
past = stack.length - 1;
|
||||
|
||||
if (cur === ' ') {
|
||||
continue;
|
||||
}
|
||||
@ -169,8 +187,14 @@ var parseExpression = function parseExpression(expression) {
|
||||
|
||||
record += cur;
|
||||
} else if (record.length) {
|
||||
var beforeRecord = past - (record.length - 1);
|
||||
if (isVariable(record) && _.isNumber(stack[beforeRecord])) {
|
||||
stack.push('*');
|
||||
}
|
||||
stack.push(record, cur);
|
||||
record = '';
|
||||
|
||||
// numbers and decimals
|
||||
} else if (_.isNumber(stack[past]) && (_.isNumber(cur) || cur === '.')) {
|
||||
|
||||
stack[past] += cur;
|
||||
@ -199,6 +223,10 @@ var parseExpression = function parseExpression(expression) {
|
||||
}
|
||||
}
|
||||
if (record.length) {
|
||||
var beforeRecord = past - (record.length - 1);
|
||||
if (isVariable(record) && _.isNumber(stack[beforeRecord])) {
|
||||
stack.push('*');
|
||||
}
|
||||
stack.push(record);
|
||||
}
|
||||
|
||||
@ -437,5 +465,16 @@ var fixFloat = function fixFloat(number) {
|
||||
return +number.toFixed(15);
|
||||
};
|
||||
|
||||
/**
|
||||
* Recognizes variables such as x, y, z
|
||||
* @param {String} a
|
||||
* The string to check for
|
||||
* @return {Boolean}
|
||||
* true if variable, else false
|
||||
*/
|
||||
var isVariable = function isVariable(a) {
|
||||
return typeof a === 'string' && !_.isNumber(a) && !_operators2['default'][a] && a === a.toLowerCase();
|
||||
};
|
||||
|
||||
exports.isVariable = isVariable;
|
||||
exports['default'] = Equation;
|
||||
module.exports = exports['default'];
|
5
dist/tests/equation.js
vendored
5
dist/tests/equation.js
vendored
@ -30,6 +30,11 @@ describe('Equations', function () {
|
||||
_expect.expect(equation).to['throw']();
|
||||
});
|
||||
|
||||
it('should work with NumVariable expressions like 2x', function () {
|
||||
var equation = _M2['default'].equation('2x + 6y');
|
||||
_expect.expect(equation(4, 3)).to.equal(8 + 18);
|
||||
});
|
||||
|
||||
it('Test case', function () {
|
||||
var equation = _M2['default'].equation('2+x*(y+4)+z^2');
|
||||
_expect.expect(equation(2, 4, 3)).to.equal(27);
|
||||
|
58
lib/index.js
58
lib/index.js
@ -47,30 +47,44 @@ let Equation = {
|
||||
*/
|
||||
equation(expression) {
|
||||
let stack = parseExpression(expression);
|
||||
console.log(stack);
|
||||
let variables = [];
|
||||
|
||||
stack.forEach(function varCheck(a) {
|
||||
if (Array.isArray(a)) {
|
||||
return a.forEach(varCheck);
|
||||
}
|
||||
|
||||
if (typeof a === 'string' && !_.isNumber(a) &&
|
||||
!operators[a] && a === a.toLowerCase()) {
|
||||
if (isVariable(a)) {
|
||||
// grouped variables like (y) need to have their parantheses removed
|
||||
variables.push(_.removeSymbols(a));
|
||||
}
|
||||
});
|
||||
|
||||
return function(...args) {
|
||||
expression = expression.replace(/[a-z]*/g, a => {
|
||||
stack.forEach(function varCheck(a, i, arr) {
|
||||
if (Array.isArray(a)) {
|
||||
return a.forEach(varCheck);
|
||||
}
|
||||
|
||||
let index = variables.indexOf(a);
|
||||
if (index > -1) {
|
||||
return args[index] || 0;
|
||||
// grouped variables like (y) need to have their parantheses removed
|
||||
arr[i] = args[index];
|
||||
}
|
||||
return a;
|
||||
});
|
||||
|
||||
return Equation.solve(expression);
|
||||
stack = sortStack(stack);
|
||||
stack = _.parseNumbers(stack);
|
||||
stack = solveStack(stack);
|
||||
// expression = expression.replace(/[a-z]*/g, a => {
|
||||
// let index = variables.indexOf(a);
|
||||
// if (index > -1) {
|
||||
// return args[index] || 0;
|
||||
// }
|
||||
// return a;
|
||||
// });
|
||||
|
||||
return stack;
|
||||
};
|
||||
},
|
||||
|
||||
@ -118,12 +132,14 @@ const MIN_PRECEDENCE = Math.min(...PRECEDENCES);
|
||||
const parseExpression = expression => {
|
||||
let stream = new ReadStream(expression),
|
||||
stack = [],
|
||||
record = '';
|
||||
record = '',
|
||||
cur, past;
|
||||
|
||||
// Create an array of separated numbers & operators
|
||||
while (stream.next()) {
|
||||
const cur = stream.current(),
|
||||
past = stack.length - 1;
|
||||
cur = stream.current();
|
||||
past = stack.length - 1;
|
||||
|
||||
if (cur === ' ') {
|
||||
continue;
|
||||
}
|
||||
@ -134,8 +150,14 @@ const parseExpression = expression => {
|
||||
|
||||
record += cur;
|
||||
} else if (record.length) {
|
||||
let beforeRecord = past - (record.length - 1);
|
||||
if (isVariable(record) && _.isNumber(stack[beforeRecord])) {
|
||||
stack.push('*');
|
||||
}
|
||||
stack.push(record, cur);
|
||||
record = '';
|
||||
|
||||
// numbers and decimals
|
||||
} else if (_.isNumber(stack[past]) &&
|
||||
(_.isNumber(cur) || cur === '.')) {
|
||||
|
||||
@ -165,6 +187,10 @@ const parseExpression = expression => {
|
||||
}
|
||||
}
|
||||
if (record.length) {
|
||||
let beforeRecord = past - (record.length - 1);
|
||||
if (isVariable(record) && _.isNumber(stack[beforeRecord])) {
|
||||
stack.push('*');
|
||||
}
|
||||
stack.push(record);
|
||||
}
|
||||
|
||||
@ -341,4 +367,16 @@ const fixFloat = number => {
|
||||
return +number.toFixed(15);
|
||||
};
|
||||
|
||||
/**
|
||||
* Recognizes variables such as x, y, z
|
||||
* @param {String} a
|
||||
* The string to check for
|
||||
* @return {Boolean}
|
||||
* true if variable, else false
|
||||
*/
|
||||
export const isVariable = a => {
|
||||
return typeof a === 'string' && !_.isNumber(a) &&
|
||||
!operators[a] && a === a.toLowerCase();
|
||||
};
|
||||
|
||||
export default Equation;
|
||||
|
@ -23,6 +23,11 @@ describe('Equations', () => {
|
||||
expect(equation).to.throw();
|
||||
});
|
||||
|
||||
it('should work with NumVariable expressions like 2x', () => {
|
||||
let equation = M.equation('2x + 6y');
|
||||
expect(equation(4, 3)).to.equal(8 + 18);
|
||||
});
|
||||
|
||||
it('Test case', () => {
|
||||
let equation = M.equation('2+x*(y+4)+z^2');
|
||||
expect(equation(2, 4, 3)).to.equal(27);
|
||||
|
Loading…
Reference in New Issue
Block a user