Calculate average of array of objects per key value using reduce
Here is possibly an even more functional programming style solution, which makes use of a temporary ES6 Map object. This has the advantage over a plain object: you can turn it into an array of pairs, and chain on that to get the final result:



var data = [
    {tv: 1, radio:5, fridge:4},
    {tv: 2, radio:2, fridge:null},
    {tv: 3, radio:6, fridge:5}
];

var avg = Array.from(data.reduce(
        (acc, obj) =&gt; Object.keys(obj).reduce( 
            (acc, key) =&gt; typeof obj[key] == "number"
                ? acc.set(key, (acc.get(key) || []).concat(obj[key]))
                : acc,
        acc),
    new Map()), 
        ([name, values]) =&gt;
            ({ name, average: values.reduce( (a,b) =&gt; a+b ) / values.length })
    );

console.log(avg);




Instead of immediately summing up the values, this code first collects the different values into an array per property, in a Map, then it calculates the averages from those arrays, turning it into the desired target structure.

Alternative output structure

Personally I find it more logical to produce output that has the same structure as the input objects, so I provide this very similar alternative. Only the final map is replaced by a reduce:



var data = [
    {tv: 1, radio:5, fridge:4},
    {tv: 2, radio:2, fridge:null},
    {tv: 3, radio:6, fridge:5}
];

var avg = Array.from(data.reduce(
        (acc, obj) =&gt; Object.keys(obj).reduce( 
            (acc, key) =&gt; typeof obj[key] == "number"
                ? acc.set(key, (acc.get(key) || []).concat(obj[key]))
                : acc,
        acc),
    new Map())).reduce( 
        (acc, [name, values]) =&gt;
            Object.assign(acc, { [name]: values.reduce( (a,b) =&gt; a+b ) / values.length }),
        {}
    );

console.log(avg);




Performance improvement

As you asked in comments about performance, I tried to improve on it, without giving up on functional programming.

I took my first code version (which will be more performant than the second), and changed the first half of the algorithm: the numbers are now summed up immediately, keeping a count next to it. For this I introduced an immediately invoked (arrow) function:



var data = [
    {tv: 1, radio:5, fridge:4},
    {tv: 2, radio:2, fridge:null},
    {tv: 3, radio:6, fridge:5}
];

var avg = Array.from(data.reduce(
        (acc, obj) =&gt; Object.keys(obj).reduce( 
            (acc, key) =&gt; typeof obj[key] == "number"
                ? acc.set(key, ( // immediately invoked function:
                        ([sum, count]) =&gt; [sum+obj[key], count+1] 
                    )(acc.get(key) || [0, 0])) // pass previous value
                : acc,
        acc),
    new Map()), 
        ([name, [sum, count]]) =&gt; ({ name, average: sum/count })
    );

console.log(avg);




This stays within the functional programming rules, but I expect better performance than the first two versions I posted.