Search code examples
javascriptalasql

Grouping objects in an array by multiple keys


Initially, I've this array:

[{
    "vendorid": 1,
    "vendorname": "Vendor1",
    "maxfilelimit": 2,
    "uploadfilename": "Voice1.xlsx"
},
{
    "vendorid": 1,
    "vendorname": "Vendor1",
    "maxfilelimit": 2,
    "uploadfilename": "Ven1_Voice.xlsx"
},
{
    "vendorid": 2,
    "vendorname": "Vendor2",
    "maxfilelimit": 2,
    "uploadfilename": "Voice2.xlsx"
},
{
    "vendorid": 2,
    "vendorname": "Vendor2",
    "maxfilelimit": 2,
    "uploadfilename": "Ven2_Voice.xlsx"
}]

I want the file names in an array with no repetition of records. So, I expect the output similar to following:

[{
    "vendorid": 1,
    "vendorname": "Vendor1",
    "maxfilelimit": 2,
    "uploadfilename": ["Voice1.xlsx", "Ven1_Voice.xlsx"]
}, {
    "vendorid": 2,
    "vendorname": "Vendor2",
    "maxfilelimit": 2,
    "uploadfilename": ["Voice2.xlsx", "Ven2_Voice.xlsx"]
}]

I found some solutions like d3.js, alaSQL but not getting output as expected


Solution

  • You can use array#reduce and inside it you can store your result in an object and then extract values using Object.values().

    var data = [{"vendorid": 1,"vendorname": "Vendor1","maxfilelimit": 2,"uploadfilename": "Voice1.xlsx"},{"vendorid": 1,"vendorname": "Vendor1","maxfilelimit": 2,"uploadfilename": "Ven1_Voice.xlsx"},{"vendorid": 2,"vendorname": "Vendor2","maxfilelimit": 2,"uploadfilename": "Voice2.xlsx"},{"vendorid": 2,"vendorname": "Vendor2","maxfilelimit": 2,"uploadfilename": "Ven2_Voice.xlsx"}];
    
    var result = data.reduce((hash, obj) => {
      let key = obj.vendorid+'|' +obj.vendorname+'|' +obj.maxfilelimit;
      if(hash[key])
          hash[key].uploadfilename.push(obj.uploadfilename);
      else {
          hash[key] = obj;
          hash[key].uploadfilename = [obj.uploadfilename];
        }
       return hash; 
    },{});
    console.log(Object.values(result));
    .as-console-wrapper { max-height: 100% !important; top: 0; }