--- id: 646d44da986f2bc9b72f5fe2 title: Step 84 challengeType: 0 dashedName: step-84 --- # --description-- Declare a `toNumberList` function that takes an `args` parameter and implicitly returns the result of splitting the `args` by commas. Then chain a `map` method to your `split` method and pass in `parseFloat` as the argument to the `map` method. # --hints-- You should declare a `toNumberList` variable. ```js assert.match(code, /const\s+applyFunction\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\)\s*;?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*,\s*infix\s*\)\s*;?\s*const\s+functionCall\s*=\s*\/\(\[a-z0-9\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i\s*;?\s*(?:const|let|var)\s+toNumberList\s*=/); ``` You should use `const` to declare your `toNumberList` variable. ```js assert.match(code, /const\s+applyFunction\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\)\s*;?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*,\s*infix\s*\)\s*;?\s*const\s+functionCall\s*=\s*\/\(\[a-z0-9\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i\s*;?\s*const\s+toNumberList\s*=/); ``` Your `toNumberList` variable should be an arrow function. ```js assert.match(code, /const\s+applyFunction\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\)\s*;?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*,\s*infix\s*\)\s*;?\s*const\s+functionCall\s*=\s*\/\(\[a-z0-9\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i\s*;?\s*const\s+toNumberList\s*=\s*(\(\s*(?:args)?\s*\)|args)\s*=>/); ``` Your `toNumberList` function should have an `args` parameter. ```js assert.match(code, /const\s+applyFunction\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\)\s*;?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*,\s*infix\s*\)\s*;?\s*const\s+functionCall\s*=\s*\/\(\[a-z0-9\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i\s*;?\s*const\s+toNumberList\s*=\s*(\(\s*args\s*\)|args)\s*=>/); ``` Your `toNumberList` function should use an implicit return. ```js assert.notMatch(code, /const\s+applyFunction\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\)\s*;?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*,\s*infix\s*\)\s*;?\s*const\s+functionCall\s*=\s*\/\(\[a-z0-9\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i\s*;?\s*const\s+toNumberList\s*=\s*(\(\s*args\s*\)|args)\s*=>\s*\{/); ``` Your `toNumberList` function should return the result of calling the `.split()` method of `args`. ```js assert.match(code, /const\s+applyFunction\s*=\s*(\(\s*str\s*\)|str)\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\)\s*;?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*,\s*infix\s*\)\s*;?\s*const\s+functionCall\s*=\s*\/\(\[a-z0-9\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i\s*;?\s*const\s+toNumberList\s*=\s*(\(\s*args\s*\)|args)\s*=>\s*args\.split\(/); ``` You should split `args` on the `,` character. ```js assert.match(code, /const\s+applyFunction\s*=\s*(?:\(\s*str\s*\)|str)\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\)\s*;?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*,\s*infix\s*\)\s*;?\s*const\s+functionCall\s*=\s*\/\(\[a-z0-9\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i\s*;?\s*const\s+toNumberList\s*=\s*(?:\(\s*args\s*\)|args)\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)/); ``` You should chain the `.map()` method to the `.split()` method. ```js assert.match(code, /const\s+applyFunction\s*=\s*(?:\(\s*str\s*\)|str)\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\)\s*;?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*,\s*infix\s*\)\s*;?\s*const\s+functionCall\s*=\s*\/\(\[a-z0-9\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i\s*;?\s*const\s+toNumberList\s*=\s*(?:\(\s*args\s*\)|args)\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(/); ``` You should pass a reference to `parseFloat` as the callback to `.map()`. ```js assert.match(code, /const\s+applyFunction\s*=\s*(?:\(\s*str\s*\)|str)\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\)\s*;?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/\s*;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*,\s*infix\s*\)\s*;?\s*const\s+functionCall\s*=\s*\/\(\[a-z0-9\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i\s*;?\s*const\s+toNumberList\s*=\s*(?:\(\s*args\s*\)|args)\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\)\s*;?/); ``` # --seed-- ## --seed-contents-- ```html Functional Programming Spreadsheet
``` ```css #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; } ``` ```js 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 } --fcc-editable-region-- const applyFunction = str => { const noHigh = highPrecedence(str); const infix = /([\d.]+)([+-])([\d.]+)/; const str2 = infixEval(noHigh, infix); const functionCall = /([a-z0-9]*)\(([0-9., ]*)\)(?!.*\()/i; } --fcc-editable-region-- 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('=')) { } } ```