如何减少和映射对象数组?

时间:2017-10-11 22:37:00

标签: javascript arrays

如何减少此对象数组并将其映射到新数组?

我的数据:

var objArray = 
  [{
    state: 'NY',
    type: 'A',
    population: 100
  },
  {
    state: 'NY',
    type: 'A',
    population: 300
  },
  {
    state: 'NY',
    type: 'B',
    population: 200
  },
  {
    state: 'CA',
    type: 'A',
    population: 400
  },
  {
    state: 'CA',
    type: 'A',
    population: 400
  }];

如果条目具有相同的state AND type,我需要将其合并为一个条目并对其人口求和。

最后,我需要将它映射到这种格式的数组。

 var outputArray = [ ['A', 'NY', 400 ], ['B', 'NY', 200], ['A', 'CA', 800] ]

5 个答案:

答案 0 :(得分:6)

嗯,首先你要减少它。这可以这样做......

objArray.reduce((prev, obj) => {
    if(1 + (indx = prev.findIndex(oldObj => oldObj.type === obj.type && oldObj.state === obj.state))) {
        prev[indx].population += obj.population;
    } else {
        prev.push({...obj})
    }
    return prev;
}, [])

这会收集数组,并以某种方式修改它并在reduce回调中返回它。它将修改现有值的总体,如果它可以找到具有正确状态和类型的人口;或者它会将一个新对象附加到数组的末尾。

现在你需要映射它。

.map(obj => [ obj.type, obj.state, obj.population ])

答案 1 :(得分:1)

我建议使用lodash包(它是Javascript应用程序中非常常见的包)。它为操作数组增加了许多很棒的功能。 This post解释了如何对群组的值进行求和。您需要稍微修改此答案以考虑您的两个参数,您可以通过将groupBy命令更改为此来执行此操作:

_.groupBy(objArray, function(val){
    return val.state + "#" + val.type
})

答案 2 :(得分:1)

您可以尝试这样的事情:

var arr = Object.keys(objArray).map(function (key) { return Object.keys(objArray[key]).map(function (key) { return [[objArray[0].state, objArray[0].type, objArray[0].population],[objArray[1].state, objArray[1].type, objArray[1].population]]}); })[0][0];

答案 3 :(得分:1)

如果您知道州和类型将永远不会有某些特征,例如' _'您可以在statetype中输入密钥,例如' NY_A' - 有点像数据库中的复合键。然后,您只需使用这些键创建一个对象,添加总体,然后将它们分成一个数组:

Object.entries(
    objArray.reduce((acc,curr) => (
    acc[curr.type + '_' + curr.state] = curr.population + (acc[curr.type + '_' + curr.state] || 0)
    , acc), {}))
.map(item => [...item[0].split('_'), item[1]])

答案 4 :(得分:1)

const _ = require('lodash')

const input = [
  { state: 'NY', type: 'A', population: 100 },
  { state: 'NY', type: 'A', population: 300 },
  { state: 'NY', type: 'B', population: 200 },
  { state: 'CA', type: 'A', population: 400 },
  { state: 'CA', type: 'A', population: 400 }
]

const expected = [
  ['A', 'NY', 400],
  ['B', 'NY', 200],
  ['A', 'CA', 800]
]

const output = _(input)
  .groupBy(({ state, type }) => [state, type].join(':'))
  .mapValues((states) => states.reduce((total, { population }) => total + population, 0))
  .map((population, stateType) => {
    const [state, type] = stateType.split(':')
    return [type, state, population]
  })
  .value()

console.log(expected)
console.log(output)