2

I am currently trying to use reduce to merge objects together when objects contain the a specific value attached to the machineId key.

Beneath is the input:

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"
    }
  ]

Beneath is the expected output:

  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"
              }
        ]
    }
];

This is what I currently have as my solution:

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);

I've also tried creating an empty array and using !arr.contains() to push items into a new object but I'm struggling to get a working solution.

I'd appreciate any assistance with this.

Thanks.

2

4 Answers 4

2

you can do this

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'))

Sign up to request clarification or add additional context in comments.

Comments

2

You could take a functiion with data and key and map later the entries.

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; }

Comments

1

The initial grouping can be done using reduce. To get the final values array use Object.values on the reduce result

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; }

Comments

0

Try this solution:

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.