我如何按键对元素进行分组并使用javascript附加该特定键的值?

时间:2019-08-21 09:15:58

标签: javascript arrays json

我需要按键对元素进行分组,并使用JavaScript附加该特定键的值。以下是实际和预期数据。谁能帮我解决这个问题吗?

实际

[
    {
        "num": 152332,
        "subReport": "HS_BIT"
    },
    {
        "num": 152332,
        "subReport": "HS_LOG"
    },
    {
        "num": 152331,
        "subReport": "HS_LOG"
    },
    {
        "num": 152331,
        "subReport": "HS_GENERAL"
    }
]

期望

[
    {
        "num": 152332,
        "subReport": "HS_BIT,HS_LOG"
    },    
    {
        "num": 152331,
        "subReport": "HS_LOG,HS_GENERAL"
    }
]

4 个答案:

答案 0 :(得分:1)

您可以使用Mapreduce

let data = [{"num": 152332,"subReport": "HS_BIT"},{"num": 152332,"subReport": "HS_LOG"},{"num": 152331,"subReport": "HS_LOG"},{"num": 152331,"subReport": "HS_GENERAL"}]

let final = data.reduce((op,{num,subReport})=>{
  op.set(num, op.get(num) && (op.get(num) + ',' + subReport) ||  subReport)
  return op
},new Map())

let output = [...final].map(([num,subReport])=>({num,subReport}))

console.log(output)

答案 1 :(得分:1)

您可以这样做:

const data = [{"num": 152332,"subReport": "HS_BIT"},{"num": 152332,"subReport": "HS_LOG"},{"num": 152331,"subReport": "HS_LOG"},{"num": 152331,"subReport": "HS_GENERAL"}];
const obj = data.reduce((a, {num, subReport}) => (a[num] = a[num] ? [...a[num], subReport] : [subReport], a), {});
const result = Object.keys(obj).map(k => ({ num: k, subReport: obj[k].join(', ') }));

console.log(result);

答案 2 :(得分:0)

您可以简单地循环数组并使用num上的唯一键创建自定义对象数据结构。然后,获取对象的值以按预期制作最终数组:

var arr = [{
    "num": 152332,
    "subReport": "HS_BIT"
  },
  {
    "num": 152332,
    "subReport": "HS_LOG"
  },
  {
    "num": 152331,
    "subReport": "HS_LOG"
  },
  {
    "num": 152331,
    "subReport": "HS_GENERAL"
  }
];
let resObj = {};
arr.forEach((obj) => {
  if (resObj[obj.num]) {
    resObj[obj.num].subReport += ', ' + obj.subReport
  } else {
    resObj[obj.num] = obj;
  }
});
var resArray = Object.values(resObj);
console.log(resArray);

  

这种方法也适用于大型数组,因为复杂度仅为O(n),而使用reduce()时复杂度更高。

答案 3 :(得分:0)

您可以将reducefind一起使用:

const arr = [
  { num: 152332, subReport: 'HS_BIT' },
  { num: 152332, subReport: 'HS_LOG' },
  { num: 152331, subReport: 'HS_LOG' },
  { num: 152331, subReport: 'HS_GENERAL' }
]

const out = arr.reduce((a, o) => {
  const item = a.find(i => i.num === o.num)
  item ? (item.subReport = `${item.subReport},${o.subReport}`) : a.push(o)
  return a
}, [])

console.log(out)

但是,这将导致时间复杂度为O(n 2 )。使用地图有助于将其减少为O(n):

const arr = [
  { num: 152332, subReport: 'HS_BIT' },
  { num: 152332, subReport: 'HS_LOG' },
  { num: 152331, subReport: 'HS_LOG' },
  { num: 152331, subReport: 'HS_GENERAL' }
]
const map = new Map([])
const out = arr.reduce((a, o, i) => {
  const num = map.get(o.num)
  num + 1 ? a[num].subReport = `${a[num].subReport},${o.subReport}` : map.set(o.num, a.push(o) - 1) 
  return a
}, [])

console.log(out)