An array of values. looping many times to calculate mean, closest matching array value, and then finding its index

I have an array of values. (cols)

I want to find out which index of cols contains the value closest to the mean of cols.

Can I combine these functions so that I'm not repeating loops?

let mean = cols.reduce((prev, curr) => prev + curr) / cols.length;
let closest = cols.reduce((prev, curr) => (curr - mean) < (prev - mean) ? curr : prev);
let meanCol = cols.indexOf(closest);
• Seems like you are calculating the average, not the mean; byjus.com/maths/difference-between-average-and-mean If you wanted to actually find closest to mean, then you need only 1 loop. Mar 2 '20 at 13:25
• Hmmm... Interesting, I actually came across that link before, but because it says multiple times that 'they can be used interchangeably' I took that to mean they're the same thing! Also, I keep finding conflicting answers, such as this one saying that I am indeed doing mean: purplemath.com/modules/meanmode.htm Mar 2 '20 at 14:47
• Wikipedia agrees with you, so case closed for me. Mar 2 '20 at 16:21

You can remove the last line searching for the index since you can get the index in the reduce method.

Btw, you forgot to add Math.abs to deal with positive value when comparing.

Demo:

const cols = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

const mean = cols.reduce((prev, curr) => prev + curr, 0) / cols.length;

const { value, index } = cols.reduce((prev, curr, i) => {
// You have deal in absolute
if (Math.abs(curr - mean) < Math.abs(prev.value - mean)) {
return { value: curr, index: i }
} else {
return prev
}
}, { value: cols, index: 0 });

console.log({ mean, value, index })

A short review;

• You can't reduce an empty array, I would check for empty arrays and decide how to deal with them
• Have a think about let vs. const, mean and closest should probably be const
• You want that code in a properly named function
• Thank you. Always appreciate the details Mar 6 '20 at 9:05