首页 > 解决方案 > Average of nested objects values in Javascript

问题描述

This seems embarrassing to ask, but I'm unsure where to go from here.

I have an array of nested objects and I would like to create a new object that has the average from the original array.

const _ = require(`lodash`)

const data = JSON.parse(`
[
  {
      "thingOne": {
          "numberOne": 1758,
          "numberTwo": 97
      },
      "thingTwo": {
          "numberOne": 1758,
          "numberTwo": 97
      }
  },
  {
      "thingOne": {
          "numberOne": 1968,
          "numberTwo": 95
      },
      "thingTwo": {
          "numberOne": 2010,
          "numberTwo": 95
      }
  }
]`)

const results = {}

_.each(data, (value, key) => {
  _.each(value, (value, key) => {
    if (key in results) {
      results[key] = {
        numberOne: results[key].numberOne + value.numberOne,
        numberTwo: results[key].numberTwo + value.numberTwo,
      }
    } else {
      results[key] = value
    }
  })
})

console.log(results)

I can do this to sum up the array into a new object, but am unsure what to do from here. Do I need to loop this all over again to create an average? Any help appreciated (and I'm not required to use lodash, if there's a simpler answer).

Here's what I'm expected to get in the end:

const expected = {
  thingOne: {
    numberOne: 1863,
    numberTwo: 96,
  },
  thingTwo: {
    numberOne: 1884,
    numberTwo: 96,
  },
}

标签: javascriptlodash

解决方案


注意到您已经使用了 lodash,您可以利用_.mergeWith()

来自 lodash文档

_.mergeWith(object, sources, customizer)

此方法与 _.merge 类似,只是它接受调用以生成目标和源属性的合并值的定制器。如果定制器返回未定义,则由方法处理合并。使用六个参数调用定制器:(objValue、srcValue、key、object、source、stack)。

在我们的例子中,我们的定制器方法检索平均值,而不是合并值。

const data = JSON.parse(`
[
  {
      "thingOne": {
          "numberOne": 1758,
          "numberTwo": 97
      },
      "thingTwo": {
          "numberOne": 1758,
          "numberTwo": 97
      }
  },
  {
      "thingOne": {
          "numberOne": 1968,
          "numberTwo": 95
      },
      "thingTwo": {
          "numberOne": 2010,
          "numberTwo": 95
      }
  }
]`);


const getAvg = (data) => _.mergeWith({}, ...data, (a, b) => {
  if(_.isNumber(b)) {
    return ((b || 0) / data.length) + (_.isNumber(a) ? (a || 0) : 0);
  }
});


console.log(getAvg(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

getAvg功能的实现归功于 Ori Drori,他最初发布它是为了回答一个相关问题。


推荐阅读