Learn Functional Programming by Building a Spreadsheet - Step 57

Tell us what’s happening:

I keep getting this error when I add the map method to my rangeFromString function. “You should pass a reference to addCharacters as the callback to your .map() method.” It seems straightforward enough but nothing I have tried will pass. I have been stuck for hours looking through multiple examples of the map method on W3Schools, MDN Web docs, and a various other online sites and found nothing that will work. Can anyone offer any advice? I am not asking for the answer, just some help to lead me to the correct answer. Thanks in advance for any assistance you may provide.
David

Your code so far

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))
);

};

<!-- file: index.html -->
<!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>
/* file: styles.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;
}
/* file: script.js */
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));


// User Editable Region

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))
  );
 
};

// User Editable Region


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('=')) {

  }
}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0

Challenge Information:

Learn Functional Programming by Building a Spreadsheet - Step 57

Why have you got char2 here?

Hi @DavidEW3

First thing, the map method does not alter the original array.
Two, the same number of items in the original array is returned by the method.

If the callback function (the code between the round brackets) performs an operation on the array, then the returned array items will be modified. A new array will be returned, the original not altered in any way.

Here’s some examples of the .map() method that may help you to understand what’s going on.

numbers = [1,2,3,4,5];
console.log(numbers.map(num => num));
console.log(numbers.map(num => num + 1));
console.log(numbers.map(num => num > 2));

Here are the new arrays returned by the .map() method

Array [1,2,3,4,5];
Array [2, 3, 4, 5, 6]
Array [false, false, true, true, true]

The instruction:
image

Pass the expression asked for in the instructions as the callback.

Happy coding

1 Like

In the previous step:
const rangeExpanded = x.replace(rangeRegex, (match, char1, num1, char2, num2)
it would not accept (match, character1, num1, character2, num2). I changed my code to match the “num1” example and the test accepted it. I agree, it should probably not have accepted it. In fact, going back in and trying it again it still does not accept the full “character” word in the match area.

HA! Thank you Teller!! It simply wanted the function reference addCharacters. It was not asking for the argument/future functions YET. This was very helpful and I see that I got ahead of myself, along with the lesson, reading to deeply into the verbiage. Thanks again, I am grateful for your assistance.
Step 57
Call the .map() method on your rangeFromString() call, passing a reference to addCharacters as the callback function.
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));
}
Passed