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?

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

4 Answers4

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.

Joseph Cho
  • 4,033
  • 4
  • 26
  • 33
  • Good one!, forgot about how NaN could cause trouble – EugenSunic Mar 11 '20 at 21:20
  • @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` – Joseph Cho Mar 11 '20 at 21:32
  • What i need here with this code is: 1. Write a function named createStatue that expects to receive three arguments: name, location, and heightInMeters. – Erick Matt Mar 11 '20 at 21:45
  • I will put all that i need with this code above in the original post. – Erick Matt Mar 11 '20 at 21:46
  • @ErickMatt That function is at the top of the code provided... it's called `createStatue` – Joseph Cho Mar 11 '20 at 21:46
  • @JosephCho Yes, but there is a lot more. I've put all the quest that i have in the post. If tried your code but then i lost isTallerThan. Didn't know how to adapt it to your code. – Erick Matt Mar 11 '20 at 21:50
  • 1
    @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. – Joseph Cho Mar 11 '20 at 21:57
  • 1
    @ErickMatt anyways, this is the best and most stable answer I believe – EugenSunic Mar 11 '20 at 22:18
  • @JosephCho Sure, i know that is not a place for homework. I'm learing and writing and i know that my code might be with bugs. That is why i asked a question about the average, the rest i placed here just in case someone needs to see it full. It might have other errors but i'm my focus was on that. What i need to do, i shared just because to let you know that i have others issues and that is why your shared code for the first part wouldn't solve my issue. Sorry if it looks like 'homework', trying my best here to fix bugs. – Erick Matt Mar 11 '20 at 22:22
2

You want to be using

isNaN(statue.height)

Rather than

isNaN(statues.height)
DougM
  • 920
  • 1
  • 9
  • 21
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())
EugenSunic
  • 13,162
  • 13
  • 64
  • 86
  • 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? – Erick Matt Mar 11 '20 at 20:52
  • check the answer again – EugenSunic Mar 11 '20 at 21:04
  • 1
    Still getting a NaN as answer. I'll post my whole code so maybe it gets easier to see to problem – Erick Matt Mar 11 '20 at 21:12
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)
easrng
  • 395
  • 4
  • 10