Summing or averaging a list of objects means reducing it to a single number: you pull one number out of each element, then total those numbers (sumBy) or total-then-divide them (meanBy). These are lodash's _.sumBy and _.meanBy — the helpers you reach for when the value you want to add up lives on a property, like totalling item.price across a cart.
Implement a sumByMeanBy object with two methods. sumBy(array, iteratee) maps each element to a number and returns their sum. meanBy(array, iteratee) returns the average of those numbers — the sum divided by how many there were.
type Iteratee<T> = ((element: T) => number) | string;
const sumByMeanBy: {
sumBy<T>(array: T[], iteratee?: Iteratee<T>): number;
meanBy<T>(array: T[], iteratee?: Iteratee<T>): number;
};
The iteratee turns an element into a number. It is either a function called with each element, or a string property name looked up as element[name]. It is optional — with no iteratee, each element is treated as the number itself.
// sumBy — total a property with the string shorthand
sumBy([{ n: 4 }, { n: 2 }, { n: 8 }], 'n'); // → 14
// ...or map each element with a function
sumBy([{ n: 4 }, { n: 2 }], (o) => o.n); // → 6
// meanBy — the average of the mapped numbers (sum / length)
meanBy([{ n: 4 }, { n: 2 }, { n: 8 }], 'n'); // → 4.6666… (14 / 3)
// the two empty-array conventions differ:
sumBy([]); // → 0 (nothing to add)
meanBy([]); // → NaN (0 / 0)
element[name]. Both must produce a number.sumBy([1, 2, 3]) is 6.sumBy([]) returns 0, the starting value for addition.meanBy([]) computes 0 / 0, which is NaN. That is lodash's behavior; match it, don't guard it away.meanBy is sumBy plus one division.