Learn Advanced Array Methods by Building a Statistics Calculator - Step 27

Use the .forEach() method to loop through the array . In the callback, use the el parameter to access the counts object and increment the count for each number.

Hello, I’m having a bit of trouble with this step. I used chatGPT and it gave a good answer but it desn’t work and the error hints is not useful at all. Why is it that sometimes the hints are very clear and straight forward while other times it just doesn’t give out any useful tips.

<!-- 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" />
    <script src="./script.js"></script>
    <title>Statistics Calculator</title>
  </head>
  <body>
    <h1>Statistics Calculator</h1>
    <p>Enter a list of comma-separated numbers.</p>
    <form onsubmit="calculate(); return false;">
      <label for="numbers">Numbers:</label>
      <input type="text" name="numbers" id="numbers" />
      <button type="submit">Calculate</button>
    </form>
    <div class="results">
      <p>
        The <dfn>mean</dfn> of a list of numbers is the average, calculated by
        taking the sum of all numbers and dividing that by the count of numbers.
      </p>
      <p class="bold">Mean: <span id="mean"></span></p>
      <p>
        The <dfn>median</dfn> of a list of numbers is the number that appears in
        the middle of the list, when sorted from least to greatest.
      </p>
      <p class="bold">Median: <span id="median"></span></p>
      <p>
        The <dfn>mode</dfn> of a list of numbers is the number that appears most
        often in the list.
      </p>
      <p class="bold">Mode: <span id="mode"></span></p>
      <p>
        The <dfn>range</dfn> of a list of numbers is the difference between the
        largest and smallest numbers in the list.
      </p>
      <p class="bold">Range: <span id="range"></span></p>
      <p>
        The <dfn>variance</dfn> of a list of numbers measures how far the values
        are from the mean, on average.
      </p>
      <p class="bold">Variance: <span id="variance"></span></p>
      <p>
        The <dfn>standard deviation</dfn> of a list of numbers is the square
        root of the variance.
      </p>
      <p class="bold">
        Standard Deviation: <span id="standardDeviation"></span>
      </p>
    </div>
  </body>
</html>
/* file: styles.css */
body {
  margin: 0;
  background-color: rgb(27, 27, 50);
  text-align: center;
  color: #fff;
}

button {
  cursor: pointer;
  background-color: rgb(59, 59, 79);
  border: 3px solid white;
  color: white;
}

input {
  background-color: rgb(10, 10, 35);
  color: white;
  border: 1px solid rgb(59, 59, 79);
}

.bold {
  font-weight: bold;
}
/* file: script.js */
const getMean = (array) => array.reduce((acc, el) => acc + el, 0) / array.length;

const getMedian = (array) => {
  const sorted = array.sort((a, b) => a - b);
  const median =
    array.length % 2 === 0
      ? getMean([sorted[array.length / 2], sorted[array.length / 2 - 1]])
      : sorted[Math.floor(array.length / 2)];
  return median;
}


// User Editable Region

const getMode = (array) => {
  const counts = {};
  array.forEach((el) =>{
    if (counts[el]) {
      counts[el]++;
    } else {
      counts[el] = 1;
    }
  });
}

// User Editable Region



const calculate = () => {
  const value = document.querySelector("#numbers").value;
  const array = value.split(/,\s*/g);
  const numbers = array.map(el => Number(el)).filter(el => !isNaN(el));
  
  const mean = getMean(numbers);
  const median = getMedian(numbers);

  document.querySelector("#mean").textContent = mean;
  document.querySelector("#median").textContent = median;
}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36

Challenge Information:

Learn Advanced Array Methods by Building a Statistics Calculator - Step 27

It’s declared empty but the forEach will iterate through the array parameter and then modify the counts object to count how many times each number in the array appeared.

Yeah I figured out that part, I understand now how I should enter the values to the object but it still doesn’t work (btw I edited my first post, and changed the code).

Yes, it’s right and working.

But seems like the tests need a specific shorthand syntax to pass.

What am I supposed to do to pass this step?

the shorthand syntax is used here in this challenge you previously solved in the Music player project.

Step 67 - Music Player Project

if you solved it, you will see that the || operator is used.

which works as follows:

it will look for the first operand and if it’s true or exists it will use its value,
if not it will use the second operand.

for example:

const person = {
    name: "GhadyKeyrouz",
    languages: "JS"
}

let name = person["name"] || "Not Found";

console.log(name)   // output: GhadyKeyrouz

but if i removed the name property of the person object, it will output “Not Found”.

const person = {
    languages: "JS"
}

let name = person["name"] || "Not Found";

console.log(name)   // output: Not Found

Let me explain more,

Here i make a function named incrementOne to increase the number property of students by one.

const students = {
    number: 39
}

const incrementOne = (students) => {
    students["number"] = ( students["number"] || 0 ) + 1;
}

incrementOne(students);

console.log(students);

// output: {number:40}

Even if there is no property called number the function will make a new number property and assign to it the result of 0 + 1 which is 1.

Ohh ok I see, I think I’ve used this with local storage, when getting the value from local storage I use the or operator if there’s no value in local storage. So I should write something like this:

counts["el"] = ( counts["el"]++ || 1);

I think this should work, it checks if counts[“el”] exists and increments it or it doesn’t exist and we give it the value 1. Btw sorry for taking so long to respond, idk why but it takes a lot of time to get the notification.
Update: it didn’t work.

You are halfway there.
but a little hint, why you enclose the el in double quotes?
You are literally looking for a property called el this way.

Just little one more step,

you want to check at first if the property exist, get its value and then increment it.
if not, take the value 0 and then increment it so the new property will have the value 1 at total.

just like you did here:

take a look at my last reply, and you should get it.

I enclosed the el in quotes because that’s what I saw you did in the last reply, so counts.el and counts[“el”] look for a property called el and counts[el] will be a variable holding the name of the property which is a number in this case. So I need to remove the quotes, you said I need to check if the property exists, am I doing it right or am I missing something?

You are right, in my reply i did students["number"] cause i write the property myself as an exmaple.

But in your challenge, you want to make an object which has properties of each number as a string and the value of this string is the number of times this number appears in the array.

for example:

const counts = {
    "1": 3,
    "2": 5,
    "5": 1
}

Yep, it’s a number but when you use that number as a property for your object,
JavaScript treats all object properties as string.
So it will make the number a string property as you see above so you don’t need to enclose it in double quotes.

Alright I understand that part, but how can I check if it already exists, in the if statement I had if (counts[el]) which returns true if it exists, but without an if statement how can I check?

That’s where the || operator comes in.

It checks if what is on the left-hand side of or exist ( a truthy value )
If so, it will not look at what is on the right-hand side and automatically use that value for whatever you want.

If it doesn’t exist, it will use what is on the right-hand side which called fallback value as you might see before.

Alright so in theory this should work right? But it still doesn’t work.

counts[el] = (counts[el]++ || 1);

Wait I thing I got it, I just learned I can’t use the ++ here

1 Like

Yep it worked, I can’t use ++ in what I assume this is called a conjunction.

You are very very close.

one little thing…

this expression:

if counts[el] doesn’t exist, it will return undefined and then you do ++ which is an error and javaScript will return NaN (Not a Number).

To bypass this issue, you need to use the || only for this case.
if it exists, use it.
if not, use the 0 value.

and then lastly, increment it by one.

Just like this here at my previous reply.

Thank you so much for the help I appreciate it a lot. You clarified a lot of things to me today and helped me get through this step.

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.