JavaScript 根据值减少对象数组

JavaScript reduce array of objects based on value

当对象包含附加到 machineId 键的特定值时,我目前正在尝试使用 reduce 将对象合并在一起。

下面是输入:

var arr = [
    {
      "id":"4055",
      "severity": "High",
      "public": true,
      "machineId": "48ed3",
      "machineName": "powerb"
    },
    {
      "id":"4045",
      "severity": "High",
      "public": true,
      "machineId": "48ed3",
      "machineName": "powerb"
    },
    {
      "id":"3433",
      "severity": "High",
      "public": true,
      "machineId": "43h5",
      "machineName": "powerva"
    }
  ]

下面是预期的输出:

  var output = [
    {
        machineId: "48ed3",
        data: [
            {
                "id":"4055",
                "severity": "High",
                "public": true,
                "machineId": "48ed3",
                "machineName": "powerb"
            },
            {
                "id":"4045",
                "severity": "High",
                "public": true,
                "machineId": "48ed3",
                "machineName": "powerb"
            }
        ] 
    },
    {
        machineId: "43h5",
        data: [
            {
                "id":"3433",
                "severity": "High",
                "public": true,
                "machineId": "43h5",
                "machineName": "powerva"
              }
        ]
    }
];

这是我目前的解决方案:

const result = Array.from(new Set(cveId.map(s => s.machineId)))
.map(lab => {
return {
machineId: lab,
cveId: cveId.filter(s => s.machineId === lab).map(CVE => CVE.cveId)
}
})
  
console.log(result);

我也试过创建一个空数组并使用 !arr.contains() 将项目推送到一个新对象中,但我正在努力寻找一个可行的解决方案。

如有任何帮助,我将不胜感激。

谢谢。

可以使用 reduce 完成初始分组。要获得最终值数组,请在 reduce result

上使用 Object.values

var arr = [    {      "id":"4055",      "severity": "High",      "public": true,      "machineId": "48ed3",      "machineName": "powerb"    },    {      "id":"4045",      "severity": "High",      "public": true,      "machineId": "48ed3",      "machineName": "powerb"    },    {      "id":"3433",      "severity": "High",      "public": true,      "machineId": "43h5",      "machineName": "powerva"    }  ]
  
  let res = Object.values(arr.reduce((acc,curr)=> {
    acc[curr.machineId] = acc[curr.machineId] || {machineId:curr.machineId, data: []}
    acc[curr.machineId].data.push(curr)
    return acc
  },{}))
  
  console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; }

您可以采用带有数据和键的函数,然后映射条目。

const
    groupBy = (data, key) => Object
        .entries(data.reduce((r, o) => ((r[o[key]] ??= []).push(o), r), {}))
        .map(([k, data]) => ({ [key]: k, data})),
    data = [{ id: "4055", severity: "High", public: true, machineId: "48ed3", machineName: "powerb" }, { id: "4045", severity: "High", public: true, machineId: "48ed3", machineName: "powerb" }, { id: "3433", severity: "High", public: true, machineId: "43h5", machineName: "powerva" }]
    result = groupBy(data, 'machineId');

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

你可以做到这一点

const groupByKey = (data, key) => Object.values(
  data.reduce((res, item) => {
   const value = item[key]
   const existing = res[value] || {[key]: value, data:[]}
   return {
     ...res,
     [value] : {
       ...existing,
       data: [...existing.data, item]
     }
   } 
  }, {})
)

var arr = [
    {
      "id":"4055",
      "severity": "High",
      "public": true,
      "machineId": "48ed3",
      "machineName": "powerb"
    },
    {
      "id":"4045",
      "severity": "High",
      "public": true,
      "machineId": "48ed3",
      "machineName": "powerb"
    },
    {
      "id":"3433",
      "severity": "High",
      "public": true,
      "machineId": "43h5",
      "machineName": "powerva"
    }
  ]
  
  console.log(groupByKey(arr, 'machineId'))

试试这个解决方案:

const arr = [{"id": "4055","severity": "High","public": true,"machineId": "48ed3","machineName": "powerb"},{"id": "4045","severity": "High","public": true,"machineId": "48ed3","machineName": "powerb"},{"id": "3433","severity": "High","public": true,"machineId": "43h5","machineName": "powerva"}];

const output = [], machineIdx = {};
for (const e of arr) {
  // No records for that machineId 
  if (typeof machineIdx[e.machineId] === 'undefined') {
    // Create record for that machineId
    machineIdx[e.machineId] = output.push({
      machineId: e.machineId,
      data: []
    }) - 1;
  }
  // Spread operator to make a copy of the object
  output[machineIdx[e.machineId]].data.push({ ...e });
}

console.log(output);