Jayson G
Jayson G

Reputation: 183

find average of an array of objects

I am trying to find the average of just the females in the given array

sortArray([
    {name:'Sarah', gender:'female', age:25},
    {name:'Tom', gender:'male', age:18},
    {name:'Tim', gender:'male', age:65},
    {name:'Kim', gender:'female', age:58}
]);

this is what i have below

function averageFemale(list)
{
    let sum = 0;
    let femaleCount = 2;
    let avg = sum / femaleCount;

    for (let i = 0, i < list.length; i++)
    {
        sum += list[i];
    }

    return avg;
}

Upvotes: 18

Views: 34949

Answers (9)

Enrique Briones Arcos
Enrique Briones Arcos

Reputation: 1158

const arr= [
    {name:'Sarah', gender:'female', age:25},
    {name:'Tom', gender:'male', age:18},
    {name:'Tim', gender:'male', age:65},
    {name:'Kim', gender:'female', age:58}
]


function averageAgeByGender(array,gender){
  const getGender = (elem) => elem.gender===gender
  const average = (a,b, i, self)=> (a+b.age/self.length)
  return array.filter(getGender).reduce(average,0)
}

console.log(averageAgeByGender(arr,'female'))

Upvotes: 4

Philippe Genois
Philippe Genois

Reputation: 639

Here's my solution, which I find more flexible:

function sumOfArrayWithParameter (array, parameter) {
  let sum = null;
  if (array && array.length > 0 && typeof parameter === 'string') {
    sum = 0;
    for (let e of array) if (e && e.hasOwnProperty(parameter)) sum += e[parameter];
  }
  return sum;
}

To get the average, you'd simply use it like that:

let sum = sumOfArrayWithParameter(array, 'age');
let avg = sum / array.length;

Upvotes: 1

Shidersz
Shidersz

Reputation: 17190

This is just my approach (looping only once on the array), and based on the next mathematical formula for progressive calculation of average:

avgN = (x1 + ... + xN) / N = (x1 + ... + xN-1) / N + (xN / N)

     = (x1 + ... + xN-1) * (N-1) / (N * (N-1)) + (xN / N)

     = ((x1 + ... + xN-1) / (N-1)) * ((N-1) / N) + (xN / N)

     = avgN-1 * (N-1) / N + (xN / N)

     = ((N-1) avgN-1 + xN) / N

var sortArray = [
    {name:'Sarah', gender:'female', age:25},
    {name:'Tom', gender:'male', age:18},
    {name:'Tim', gender:'male', age:65},
    {name:'Kim', gender:'female', age:58}
];

function averageFemale(list)
{
    var count = 0;

    return list.reduce((avg, personData) =>
    {
        if (personData.gender === 'female')
            avg = (count * avg + personData.age) / (++count);

        return avg;
    },0);
}

console.log("Average age of females is: " + averageFemale(sortArray));

Upvotes: 0

baao
baao

Reputation: 73251

You can do that with a single reduce

function averageBy(arr) {
    const {total, count} = arr.reduce((a, b) => {
            if (b.gender === 'female') {
                a.total += b.age;
                a.count++;
            }
            return a;
        }, {total: 0, count: 0});
    
    return total / count;
}

console.log(averageBy(arr));
<script>
const arr = [
    {
        name: 'Sarah',
        gender: 'female',
        age: 25
    },
    {
        name: 'Tom',
        gender: 'male',
        age: 18
    },
    {
        name: 'Tim',
        gender: 'male',
        age: 65
    },
    {
        name: 'Kim',
        gender: 'female',
        age: 58
    }
];
</script>

Upvotes: 3

Barmar
Barmar

Reputation: 781706

You need to check the gender before adding the age to sum, and also increment femaleCount instead of hard-coding it to 2.

There's also no need to re-calculate avg every time through the loop, you can do it once at the end.

function averageFemale(list) {
  let sum = 0;
  let femaleCount = 0;
  for (let i = 0; i < list.length; i++) {
    if (list[i].gender == 'female') {
      sum += list[i].age;
      femaleCount++;
    }
  }
  if (femaleCount == 0) {
    return 0; // prevent division by 0
  }
  let avg = sum / femaleCount;
  return avg;
}

console.log(averageFemale([{name:'Sarah', gender:'female', age:25}, {name:'Tom', gender:'male', age:18}, {name:'Tim', gender:'male', age:65}, {name:'Kim', gender:'female', age:58}]));

You also had a typo in the for loop header, , should be ;.

Upvotes: 3

Mohammad Usman
Mohammad Usman

Reputation: 39342

You can also:

  • Filter the input array using .filter() to get only objects having gender as female.
  • Use .reduce() to get the sum of ages.
  • Calculate average by dividing the above calculated sum by the numbers of objects in filtered array.

Demo:

let data = [
  {name:'Sarah', gender:'female', age:25},
  {name:'Tom', gender:'male', age:18},
  {name:'Tim', gender:'male', age:65},
  {name:'Kim', gender:'female', age:58}
];

let filteredData = data.filter(({ gender }) => gender == 'female'),
    avg = filteredData.reduce((r, c) => r + c.age, 0) / filteredData.length;
                 
console.log(avg);

Upvotes: 6

Jeff Wooden
Jeff Wooden

Reputation: 5489

Here is a way to do it by reducing the age of the females and dividing by total females:

const data = [{name:'Sarah', gender:'female', age:25}, {name:'Tom', gender:'male', age:18}, {name:'Tim', gender:'male', age:65}, {name:'Kim', gender:'female', age:58}];

let count = 0;
const average = data.reduce((total, person) => {
  if (person.gender === 'female') {
  	total += person.age;
    count++;
  }
  return total;
}, 0) / count;

console.log(average);

Upvotes: 0

KevBot
KevBot

Reputation: 18908

You can filter out "females" to a new array, and then reduce that down to a total of all ages, then use the length of the females array to divide the total by:

const people = [{name:'Sarah', gender:'female', age:25}, {name:'Tom', gender:'male', age:18}, {name:'Tim', gender:'male', age:65}, {name:'Kim', gender:'female', age:58}];

const females = people.filter(person => person.gender === 'female');

const average = females.reduce((total, next) => total + next.age, 0) / females.length;

console.log(average);

Upvotes: 44

Nina Scholz
Nina Scholz

Reputation: 386670

You need to check the gender property and take sum age and increment a counter, because you do not know that in advance.

function averageFemale(list) {
    var sum = 0,
        count = 0,
        i;

    for (i = 0; i < list.length; i++) {
        if (list[i].gender === 'female') {
            sum += list[i].age;
            ++count;
        }
    }
    return sum / count;
}

var array = [{ name: 'Sarah', gender: 'female', age: 25 }, { name: 'Tom', gender: 'male', age: 18 }, { name: 'Tim', gender: 'male', age: 65 }, { name: 'Kim', gender: 'female', age: 58 }];

console.log(averageFemale(array));

Upvotes: 1

Related Questions