curriculum/challenges/english/blocks/learn-functional-programming-by-building-a-spreadsheet/646d40fe4b7b50c30c2b4cd8.md
Your infixEval function will only evaluate the first multiplication or division operation, because regex isn't global. This means you'll want to use a recursive approach to evaluate the entire string.
If infixEval does not find any matches, it will return the str value as-is. Using a ternary expression, check if str2 is equal to str. If it is, return str, otherwise return the result of calling highPrecedence() on str2.
Your highPrecedence function should use the return keyword.
assert.match(code, /const\s+highPrecedence\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\)\s*;?\s*return/);
You should use the return keyword with a condition to check if str is equal to str2.
assert.match(code, /const\s+highPrecedence\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\)\s*;?\s*return\s+(?:str\s*===\s*str2|str2\s*===\s*str)/);
You should use ternary syntax with your return statement.
assert.match(code, /const\s+highPrecedence\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\)\s*;?\s*return\s+(?:str\s*===\s*str2|str2\s*===\s*str)\s*\?/);
If the ternary condition is true, you should return str.
assert.match(code, /const\s+highPrecedence\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\)\s*;?\s*return\s+(?:str\s*===\s*str2|str2\s*===\s*str)\s*\?\s*str/);
If the ternary condition is false, you should return the result of calling highPrecedence().
assert.match(code, /const\s+highPrecedence\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\)\s*;?\s*return\s+(?:str\s*===\s*str2|str2\s*===\s*str)\s*\?\s*str\s*:\s*highPrecedence\(/);
You should pass str2 to your highPrecedence() call.
assert.match(code, /const\s+highPrecedence\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\)\s*;?\s*return\s+(?:str\s*===\s*str2|str2\s*===\s*str)\s*\?\s*str\s*:\s*highPrecedence\(\s*str2\s*\)/);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="./styles.css" />
<title>Functional Programming Spreadsheet</title>
</head>
<body>
<div id="container">
<div></div>
</div>
<script src="./script.js"></script>
</body>
</html>
#container {
display: grid;
grid-template-columns: 50px repeat(10, 200px);
grid-template-rows: repeat(11, 30px);
}
.label {
background-color: lightgray;
text-align: center;
vertical-align: middle;
line-height: 30px;
}
const infixToFunction = {
"+": (x, y) => x + y,
"-": (x, y) => x - y,
"*": (x, y) => x * y,
"/": (x, y) => x / y,
}
const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2)));
--fcc-editable-region--
const highPrecedence = str => {
const regex = /([\d.]+)([*\/])([\d.]+)/;
const str2 = infixEval(str, regex);
}
--fcc-editable-region--
const isEven = num => num % 2 === 0;
const sum = nums => nums.reduce((acc, el) => acc + el, 0);
const average = nums => sum(nums) / nums.length;
const median = nums => {
const sorted = nums.slice().sort((a, b) => a - b);
const length = sorted.length;
const middle = length / 2 - 1;
return isEven(length)
? average([sorted[middle], sorted[middle + 1]])
: sorted[Math.ceil(middle)];
}
const spreadsheetFunctions = {
sum,
average,
median
}
const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index);
const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code));
const evalFormula = (x, cells) => {
const idToText = id => cells.find(cell => cell.id === id).value;
const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi;
const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2));
const elemValue = num => character => idToText(character + num);
const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num));
const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2)));
const cellRegex = /[A-J][1-9][0-9]?/gi;
const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase()));
}
window.onload = () => {
const container = document.getElementById("container");
const createLabel = (name) => {
const label = document.createElement("div");
label.className = "label";
label.textContent = name;
container.appendChild(label);
}
const letters = charRange("A", "J");
letters.forEach(createLabel);
range(1, 99).forEach(number => {
createLabel(number);
letters.forEach(letter => {
const input = document.createElement("input");
input.type = "text";
input.id = letter + number;
input.ariaLabel = letter + number;
input.onchange = update;
container.appendChild(input);
})
})
}
const update = event => {
const element = event.target;
const value = element.value.replace(/\s/g, "");
if (!value.includes(element.id) && value.startsWith('=')) {
}
}