Created
November 8, 2020 19:52
-
-
Save audrenbdb/94fcaa1e17a8e5db8166c04927259d40 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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")); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I had to stop at line 20 because I 'm unable to understand starting from line 21.