175 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| ---
 | |
| id: 5d792534408c5be896b0a46e
 | |
| title: Part 037
 | |
| challengeType: 0
 | |
| isBeta: true
 | |
| ---
 | |
| 
 | |
| ## Description
 | |
| <section id='description'>
 | |
| 
 | |
| The `hasOwnProperty` method checks if a key exists in an object. So `spreadsheetFunctions.hasOwnProperty("")` would return `true`, but replacing `""` with anything else would make it return `false`.
 | |
| 
 | |
| Chain `hasOwnProperty` to `spreadsheetFunctions` to check if the `fn.toLowerCase()` key exists in `spreadsheetFunctions`.
 | |
| 
 | |
| </section>
 | |
| 
 | |
| ## Instructions
 | |
| <section id='instructions'>
 | |
| 
 | |
| 
 | |
| </section>
 | |
| 
 | |
| ## Tests
 | |
| <section id='tests'>
 | |
| 
 | |
| ```yml
 | |
| tests:
 | |
|   - text: See description above for instructions.
 | |
|     testString: assert(code.replace(/\s/g, "").includes("returnstr2.replace(regex,(match,fn,args)=>spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()))"));
 | |
| 
 | |
| ```
 | |
| 
 | |
| 
 | |
| </section>
 | |
| 
 | |
| ## Challenge Seed
 | |
| <section id='challengeSeed'>
 | |
| 
 | |
| <div id='html-seed'>
 | |
| 
 | |
| ```html
 | |
| <script>
 | |
| 
 | |
| 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, (_, arg1, fn, arg2) =>
 | |
|     infixToFunction[fn](parseFloat(arg1), parseFloat(arg2))
 | |
|   );
 | |
| 
 | |
| const highPrecedence = str => {
 | |
|   const regex = /([0-9.]+)([*\/])([0-9.]+)/;
 | |
|   const str2 = infixEval(str, regex);
 | |
|   return str === str2 ? str : highPrecedence(str2);
 | |
| };
 | |
| 
 | |
| const spreadsheetFunctions = {
 | |
|   "": x => x
 | |
| };
 | |
| 
 | |
| const applyFn = str => {
 | |
|   const noHigh = highPrecedence(str);
 | |
|   const infix = /([0-9.]+)([+-])([0-9.]+)/;
 | |
|   const str2 = infixEval(noHigh, infix);
 | |
|   const regex = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i;
 | |
|   const toNumberList = args => args.split(",").map(parseFloat);
 | |
|   const applyFunction = (fn, args) =>
 | |
|     spreadsheetFunctions[fn.toLowerCase()](toNumberList(args));
 | |
|   return str2.replace(regex, (match, fn, args) => spreadsheetFunctions);
 | |
| }
 | |
| 
 | |
| 
 | |
| </script>
 | |
| ```
 | |
| 
 | |
| </div>
 | |
| 
 | |
| 
 | |
| ### Before Test
 | |
| <div id='html-setup'>
 | |
| 
 | |
| ```html
 | |
| <!DOCTYPE html>
 | |
| <html lang="en">
 | |
| <head>
 | |
|   <meta charset="UTF-8">
 | |
|   <title>Spreadsheet</title>
 | |
|   <style>
 | |
|     #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;
 | |
|     }
 | |
|   </style>
 | |
| </head>
 | |
| <body>
 | |
| <div id="container">
 | |
|   <div></div>
 | |
| </div>
 | |
| ```
 | |
| 
 | |
| </div>
 | |
| 
 | |
| 
 | |
| ### After Test
 | |
| <div id='html-teardown'>
 | |
| 
 | |
| ```html
 | |
| </body>
 | |
| </html>
 | |
| ```
 | |
| 
 | |
| </div>
 | |
| 
 | |
| 
 | |
| 
 | |
| </section>
 | |
| 
 | |
| ## Solution
 | |
| <section id='solution'>
 | |
| 
 | |
| ```html
 | |
| <script>
 | |
| 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, (_, arg1, fn, arg2) =>
 | |
|     infixToFunction[fn](parseFloat(arg1), parseFloat(arg2))
 | |
|   );
 | |
| 
 | |
| const highPrecedence = str => {
 | |
|   const regex = /([0-9.]+)([*\/])([0-9.]+)/;
 | |
|   const str2 = infixEval(str, regex);
 | |
|   return str === str2 ? str : highPrecedence(str2);
 | |
| };
 | |
| 
 | |
| const spreadsheetFunctions = {
 | |
|   "": x => x
 | |
| };
 | |
| 
 | |
| const applyFn = str => {
 | |
|   const noHigh = highPrecedence(str);
 | |
|   const infix = /([0-9.]+)([+-])([0-9.]+)/;
 | |
|   const str2 = infixEval(noHigh, infix);
 | |
|   const regex = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i;
 | |
|   const toNumberList = args => args.split(",").map(parseFloat);
 | |
|   const applyFunction = (fn, args) =>
 | |
|     spreadsheetFunctions[fn.toLowerCase()](toNumberList(args));
 | |
|   return str2.replace(
 | |
|     regex,
 | |
|     (match, fn, args) =>
 | |
|       spreadsheetFunctions.hasOwnProperty(fn.toLowerCase())
 | |
|   );
 | |
| }
 | |
| </script>
 | |
| ```
 | |
| 
 | |
| </section>
 |