7

Then I need a function that gets the average high. Here is what i did:

    function getAverageHeight() {
        let total_height = 0;
        let average_height = statues.length;

        if (statues.length > 0) {
            for (let i = 0; i < statues.length; i++) {
                let statue = statues[i];

                total_height += isNaN(statues.height) ? 0 : statue.height;
            }
        average_height = (total_height / statues.length).toFixed(2);
         }
       return average_height;
       } 

But when i test it i got NaN as as response not the average. What I did wrong here? Can someone give a clue?

3
  • 2
    isNaN(statues.height) should be isNaN(statue.height). Also, initializing the average with the length of the array doesn't make sense. Commented Mar 11, 2020 at 20:06
  • 2
    by usig functional programming you would certainly not run into such mistake Commented Mar 11, 2020 at 20:11
  • You could simplify your average function by adapting this: stackoverflow.com/a/10624256/1024832 Commented Mar 11, 2020 at 20:27

4 Answers 4

3

A lot of the solutions here are pretty good, but there are edge cases with isNan like true and ''. It's safer to use parseInt first. Here's a solution that tosses out edge cases and returns the average.

let statues = [];
function createStatue(name, city, heightInMeters) {
  statues.push({
    name,
    city,
    heightInMeters
  });
}

// create statues + edge cases inputs
createStatue("Number", "New York", 46);
createStatue("Decimal", "Florence", 5.17);
createStatue("String", "Florence", '123');
createStatue("True", "Boston", true);
createStatue("Empty", "New York City", '');


function getAverageHeight() {
  // Filter out bad cases here
  const filteredStatues = statues.filter((x) => {
    let num = parseInt(x.heightInMeters);
    return !isNaN(num);
  });

  const total = filteredStatues.reduce((acc, x) => {
    return acc+parseInt(x.heightInMeters);
  }, 0);
  return (total/filteredStatues.length).toFixed(2);
}

console.log(getAverageHeight());

EDIT: The OP has provided the original code. Looking at it there are some oddities.

heightInMeters: heightInMeters,
  isLongerThan: function (other_statue) {            
    return this.highInMeters > other_statue.hightInMeters;

It looks like there are several typos here and the code shouldn't run.

Sign up to request clarification or add additional context in comments.

9 Comments

Good one!, forgot about how NaN could cause trouble
@EugenSunic Thanks. I looked at your code and it's good. The reason it doesn't work is the original code has heightInMeters not height
What i need here with this code is: 1. Write a function named createStatue that expects to receive three arguments: name, location, and heightInMeters.
@ErickMatt isTallerThan never worked to begin with. There are typos in your function. Please keep in mind Stackoverflow is a place to debug not assist with homework.
@ErickMatt anyways, this is the best and most stable answer I believe
|
2

You want to be using

isNaN(statue.height)

Rather than

isNaN(statues.height)

3 Comments

That typo wouldn't cause it to result in NaN though. It would cause it to result in "0.00". Something else is causing NaN.
I did that and now i'm getting 0.00 as a result
@ErickMatt try my answer
1

Create a function which accumulates objects in an array each time it is called.

Create a separate average function which takes that accumulated array and returns the average results of height if height is a number

let statues = [];
function createStatue(name, city, height) {
  return statues = [...statues, {
    name,
    city,
    height
  }]
}
// call functions to populate array
createStatue("Statue of Liberty", "New York", 46);
createStatue("Christ the Redeemer", "Rio de Janeiro", 30);
createStatue("David", "Florence", 5.17);
createStatue("Little Mermaid", "Copenhagen", 1.25);
createStatue("Winged Victory", "Paris", 2.44);
createStatue("Venus de Milo", "Paris", 2);


function getAverageHeight() {
  const total = statues.reduce((acc, x) => {
    if (!isNaN(x.height)) {
      acc.counter += 1
      acc.sum += x.height;
    }
    return acc;
  }, {
    sum: 0,
    counter: 0
  })
  return (total.sum / total.counter).toFixed(2)

}

console.log(getAverageHeight())

3 Comments

That seems a good solution but the fact is that i need to create a variable named statues and assign to it an array. This array should contain this six objects that are created by calling the createStatue function. Can i adapt it somehow?
check the answer again
Still getting a NaN as answer. I'll post my whole code so maybe it gets easier to see to problem
1

You are needlessly setting the default value of average_height, and you accidentally typed "statues" instead of statue.

function getAverageHeight() {
    let total_height = 0;
    let average_height = "0.00"; // ⭐ This will be returned when statues.length <= 0

    if (statues.length > 0) {
        for (let i = 0; i < statues.length; i++) {
            let statue = statues[i];
            total_height += isNaN(statue.height) ? 0 : statue.height; // ⭐ You meant statue.height, not statues.height
        }
        average_height = (total_height / statues.length).toFixed(2)
    }
    return average_height;
}

Or you could use Array.reduce, like this:

let getAverageHeight = () => (statues.reduce((a, b) => {
    a += b.height;
    return a
}, 0) / statues.length || 0).toFixed(2)

2 Comments

Got a 0.00 as an answer.
Could you elaborate please?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.