Reputation: 183
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
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
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
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
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
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
Reputation: 39342
You can also:
.filter()
to get only objects having gender
as female
..reduce()
to get the sum of ages.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
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
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
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