Skip to content

Instantly share code, notes, and snippets.

@audrenbdb
Created November 8, 2020 19:52
Show Gist options
  • Save audrenbdb/94fcaa1e17a8e5db8166c04927259d40 to your computer and use it in GitHub Desktop.
Save audrenbdb/94fcaa1e17a8e5db8166c04927259d40 to your computer and use it in GitHub Desktop.
/* calculator in javascript using functional programming principles */
const operators = ["+", "*", "-", "/"];
//isOperator checks if a given character is an operator
const isOperator = char => operators.includes(char);
/* all operations to be used */
const operations = {
"/": (a, b) => a / b,
"*": (a, b) => a * b,
"+": (a, b) => a + b,
"-": (a, b) => a - b,
}
/* mergeOperation merge an operation around a given operator index
i.e : mergeOperation(["13", "+", "6", "*", "2"], 3)
--> ["13", "+", "12"]
*/
const mergeOperation = (calculation, i) => {
if (i === -1) return calculation;
const result = operations[calculation[i]](+calculation[i-1], +calculation[i+1]);
return calculation.map((item, j) => i - 1 === j ? result : item)
.filter((item, j) => j < i || j > i + 1);
}
/* getNextOperatorIndex retrieves the next operator index of a calculation array
prioritizing * and / operator
*/
const getNextOperatorIndex = calculation => {
const nextIndex = calculation.findIndex(operator => ["*", "/"].includes(operator));
return nextIndex !== -1 ?
nextIndex :
calculation.findIndex(operator => ["+", "-"].includes(operator));
}
/* operate reduces recursively a calculation untils all its operations have been done
i.e : ["13", "+", "6", "*", "2"]
--> ["13", "+", 12]
--> 25
*/
const operate = (calculation) => {
if (calculation.length === 1) return calculation[0];
return operate(mergeOperation(calculation, getNextOperatorIndex(calculation)))
}
/* formatCalculation converts a calculation string to an array
i.e : "13+6*2"
--> ["13", "+", "6", "*", "2"]
*/
const formatCalculation = (calculationString, arr = "") => {
if (!calculationString) return arr.split(" ");
const firstChar = calculationString[0];
return formatCalculation(
calculationString.slice(1),
arr.concat(isOperator(firstChar) ? ` ${firstChar} ` : firstChar)
)
}
/* takes a calculation string and returns a result */
const calculate = calculationString => {
const calculation = formatCalculation(calculationString)
return operate(calculation, getNextOperatorIndex(calculation));
}
console.log(calculate("13+6*2"));
Copy link

ghost commented Sep 30, 2022

I had to stop at line 20 because I 'm unable to understand starting from line 21.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment