curriculum/challenges/english/blocks/learn-functional-programming-by-building-a-spreadsheet/646d4769ba65f1d05ef6b634.md
Now your update() function can actually evaluate formulas. Remember that you wrote the if condition to check that a function was called.
Inside your if statement, set the value of the element to be the result of your evalFormula() function. Do not pass any arguments yet.
You should update the value property of element in your if block.
assert.match(code, /const\s+update\s*=\s*(?:\(\s*event\s*\)|event)\s*=>\s*\{\s*const\s+element\s*=\s*event\.target\s*;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\)\s*;?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\s*\[\s*0\s*\]\s*===\s*('|"|`)=\3|value\.charAt\(\s*0\s*\)\s*===\s*('|"|`)=\4|value\.startsWith\(\s*('|"|`)=\5\s*\))|(?:value\s*\[\s*0\s*\]\s*===\s*('|"|`)=\6|value\.charAt\(\s*0\s*\)\s*===\s*('|"|`)=\7|value\.startsWith\(\s*('|"|`)=\8\s*\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value/);
You should assign the value property the result of calling your evalFormula() function.
assert.match(code, /const\s+update\s*=\s*(?:\(\s*event\s*\)|event)\s*=>\s*\{\s*const\s+element\s*=\s*event\.target\s*;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\)\s*;?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\s*\[\s*0\s*\]\s*===\s*('|"|`)=\3|value\.charAt\(\s*0\s*\)\s*===\s*('|"|`)=\4|value\.startsWith\(\s*('|"|`)=\5\s*\))|(?:value\s*\[\s*0\s*\]\s*===\s*('|"|`)=\6|value\.charAt\(\s*0\s*\)\s*===\s*('|"|`)=\7|value\.startsWith\(\s*('|"|`)=\8\s*\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value\s*=\s*evalFormula\(/);
You should not pass any arguments to your evalFormula() call.
assert.match(code, /const\s+update\s*=\s*(?:\(\s*event\s*\)|event)\s*=>\s*\{\s*const\s+element\s*=\s*event\.target\s*;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\)\s*;?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\s*\[\s*0\s*\]\s*===\s*('|"|`)=\3|value\.charAt\(\s*0\s*\)\s*===\s*('|"|`)=\4|value\.startsWith\(\s*('|"|`)=\5\s*\))|(?:value\s*\[\s*0\s*\]\s*===\s*('|"|`)=\6|value\.charAt\(\s*0\s*\)\s*===\s*('|"|`)=\7|value\.startsWith\(\s*('|"|`)=\8\s*\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value\s*=\s*evalFormula\(\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)));
const highPrecedence = str => {
const regex = /([\d.]+)([*\/])([\d.]+)/;
const str2 = infixEval(str, regex);
return str === str2 ? str : highPrecedence(str2);
}
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 applyFunction = str => {
const noHigh = highPrecedence(str);
const infix = /([\d.]+)([+-])([\d.]+)/;
const str2 = infixEval(noHigh, infix);
const functionCall = /([a-z0-9]*)\(([0-9., ]*)\)(?!.*\()/i;
const toNumberList = args => args.split(",").map(parseFloat);
const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args));
return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match);
}
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()));
const functionExpanded = applyFunction(cellExpanded);
return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells);
}
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);
})
})
}
--fcc-editable-region--
const update = event => {
const element = event.target;
const value = element.value.replace(/\s/g, "");
if (!value.includes(element.id) && value.startsWith('=')) {
}
}
--fcc-editable-region--