11

I have an array with properties, take the following for example:

var arrayPeople = [
    {
        name: 'joe',
        job: 'programmer',
        age: 25,
    },
    {
        name: 'bob',
        job: 'plumber',
        age: 30,
    };
];

I want to create a function that will return their average ages, here is what i have that is currently not working

var ageAverage = function(array) {
    var age = 0, average;
    for (var i = 0; i < array.length; i++) {
        age += array[i].age;
    }
    average = age / array.length;
    return average;
};

What I am getting when running this function is Not A Number

But what I can get to work is:

var ageAverage = function(array) {
    var age = 0, average;
    for (var i = 0; i < array.length; i++) {
        age = array[0].age;
    }
    average = age / array.length;
    return average;
};

The subtle difference here is that I took away the += and just made it =, and i took away the use of our variable i and just gave it the first index of the array. So in doing this, I know that the function is correctly substituting the parameter array with arrayPeople, but there is something going wrong in my for loop that is stopping i from becoming 0 and 1 (the indexes of arrayPeople).

P.S. I am trying to do this on my own, and I am not looking for someone to just do the problem for me, I would really appreciate just some hints on what to fix or maybe a concept I need to research the understand how to fix this problem.

Thanks!!

Brandon
  • 335
  • 2
  • 4
  • 15
  • Try transforming array[i].age into a number. Also initialize variables, it is good practice. Dont use array as a name of a variable, in some languages it is a reserved word. Also check your array of objects, there are some mistakes (commas and semicolon) – acontell Jan 10 '15 at 18:49
  • sum of values of a specific property in an array of objects: `ARRAYNAME.reduce(function (a,b) { return a + b.PROPERTYNAME; }, 0)` – ashleedawg Sep 18 '20 at 02:48

4 Answers4

34

Consider using map and reduce:

arrayPeople.
  map(function(item){ return item.age; }).
  reduce(function(a, b){ return a + b; }, 0) / arrayPeople.length;

Or just the reduce as @KooiInc pointed out:

arrayPeople.reduce(function (a,b) { return a + b.age; }, 0) / arrayPeople.length;

A working Example:

var arrayPeople = [{
    name: 'joe',
    job: 'programmer',
    age: 25,
  }, {
    name: 'bob',
    job: 'plumber',
    age: 30,
  }],
  average = arrayPeople.reduce(function(a, b) {
    return a + b.age;
  }, 0) / arrayPeople.length;

document.write(average);
CD..
  • 72,281
  • 25
  • 154
  • 163
  • 4
    You don't need the mapping part: `arrayPeople.reduce(function (a,b) {return a + +b.age;}, 0);` – KooiInc Jan 10 '15 at 18:57
  • Thanks, this is new to me and I have been researching it, one thing I can't find though is how to call this. can I store this in a variable? I am ultimately using the value of the output in an innerHTML that will show the average number on an html page, so i need to have something like: document.getElementById('htmlid').innerHTML = " The average is " + (our answer for this problem here); – Brandon Jan 10 '15 at 19:04
5

You need initialize age variable (var age = 0)

var arrayPeople = [{
  name: 'joe',
  job: 'programmer',
  age: 25,
}, {
    name: 'bob',
    job: 'plumber',
    age: 30,
}];

var ageAverage = function(array) {
  var age = 0,
      average;

  for (var i = 0; i < array.length; i++) {
    age += array[i].age;
  }

  average = age / array.length;
  return average;
};

console.log(
  ageAverage(arrayPeople)
);

in your variant, age variable equals undefined, and undefined += number (for example 25) returns NaN;

also change , to ; in this line

from

for (var i = 0, i < array.length; i++) {

to

for (var i = 0; i < array.length; i++) {
Oleksandr T.
  • 76,493
  • 17
  • 173
  • 144
3

There's always a one-liner.

arrayPeople.reduce((a, o, i, p) => a + o.age / p.length, 0));

console.log(`${[{
    name: 'joe',
    job: 'programmer',
    age: 25,
  },
  {
    name: 'bob',
    job: 'plumber',
    age: 30,
  }
].reduce((a, o, i, p) => a + o.age / p.length, 0)}%`);
Ricky Ruiz
  • 25,455
  • 6
  • 44
  • 53
  • It doesn't work. It gives [Object][Object] for 'a' where you do a + o.age. Though I am using reduce for getting sum of age for all objects in the array, logic is the same. When I did a.age + o.age, it worked, but still it gives issue when there is a single element in the array. – shanti Dec 21 '17 at 07:39
  • Hi @shanti, most probably you are passing an object as initial value in the reduce method, could you provide a working example of your code? If a.age worked, your accumulator (a) is an object instead of a number. – Ricky Ruiz Dec 21 '17 at 15:54
  • 1
    The first argument in the reduce method is an accumulator, the second is the current item in the expense list. Try this: `expenseList.reduce((totalExpense, currentExpense) => { return totalExpense + currentExpense.amount }, 0)`. There is no need to access `amount` property in `totalExpense` because that is the result (accumulator). Hope I was clear, I'm on my phone. If there's any doubt feel free to tell me, I'll grab my lap to provide an example. – Ricky Ruiz Dec 25 '17 at 09:27
  • Sorry, my previous comment was deleted by mistake. This is my previous comment - "I used it like this, expenseList.reduce((expense1, expense2) => { return expense1.amount + expense2.amount }, 0), Yes, so angular is considering accumulator as an object. This works if I have more than 1 expense in my list. If there is just one list item, it gives NaN for the sum" [Previous comment ends] ---- – shanti Dec 25 '17 at 09:35
  • I started with totalExpense first, but on debugging, it gave me [object][object] for totalExpense and NaN for the sum. My expense list is the list of expense objects. I will try once more and update here. – shanti Dec 25 '17 at 09:36
  • Sorry, it is definitely working today. I don't remember how I was seeing that issue earlier. My bad...Thanks for your help. :) – shanti Dec 25 '17 at 09:50
  • 1
    No worries, any time! Here's an example anyways https://jsfiddle.net/5gr44co6/ `:-)` – Ricky Ruiz Dec 25 '17 at 09:53
  • @shanti Use [object destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring) if you just want to access the amount property: https://jsfiddle.net/95623cxt/ – Ricky Ruiz Dec 25 '17 at 10:00
2

You should change the for to:

for (var i = 0; i < array.length; i++) instead of for (var i = 0, i < array.length; i++)

and give initial value to age

var age=0
Mouhamad Kawas
  • 370
  • 2
  • 12