MysteryPancake
MysteryPancake

Reputation: 1505

JavaScript: Get average object in array?

I'm trying to think of a way to make this code simple, with the smallest amount of loops and variables, but I'm having trouble.

I want to get the average object in the array 'numbers', based on the 'value'. I feel that there must be a mathematical way to get the average without finding the closest average in another loop.

Currently I have this mess:

var numbers = [
	{ value: 41 },
	{ value: 19 },
	{ value: 51 },
	{ value: 31 },
	{ value: 11 }
];
// Find average:
var sum = 0;
for (var i = 0; i < numbers.length; i++) {
	sum += numbers[i].value;
}
var average = sum / numbers.length;
// Find closest object to average:
var match, difference;
for (var j = 0; j < numbers.length; j++) {
	const diff = Math.abs(average - numbers[j].value);
	if (difference === undefined || diff < difference) {
		difference = diff;
		match = numbers[j];
	}
}
// Print junk:
console.log("AVERAGE NUMBER: " + average);
console.log("CLOSEST OBJECT: " + match);
console.log("CLOSEST NUMBER: " + match.value);

I need to retrieve the object because it contains other information that I need to use.

Any help would be highly appreciated!

Upvotes: 7

Views: 4384

Answers (1)

Nina Scholz
Nina Scholz

Reputation: 386766

At least you need two loops for getting the average and the closest item, because you need to visit all items in the first run and you do not have the possibillity to store in advance which item has the closest value.

You could get first the average and then reduce the closest value with the object.

var numbers = [{ value: 41 }, { value: 19 }, { value: 51 }, { value: 31 }, { value: 11 }, { value: 30 }],
    average = numbers.reduce((sum, { value }) => sum + value, 0) / numbers.length,
    closest = numbers.reduce((a, b) =>
        Math.abs(average - a.value) <= Math.abs(average - b.value)
            ? a
            : b
    );

console.log(average);
console.log(closest);

Upvotes: 7

Related Questions