-1

I have an Array of Objects so that depending on a certain key's value I'd like to create a new array of objects with that particular key.

For eg, I have an array of Users

{
    association: "template"
    color: "(255, 209, 0, 0.35)"
    email: "ehe@example.com"
    id: "12158_2"
    name: "sevderadebvu"
    rolename: "Floyd Phelps"
    templateId: 8888
    type: "template"
},
{
    association: "template"
    color: "(0, 7, 255, 0.35)"
    email: "unoja@host.local"
    id: "12158_3"
    name: "ekdevajwirum"
    rolename: "Virginia Martin"
    templateId: 8888
    type: "template"
},
{
    association: "template"
    color: "(255, 121, 169, 0.35)"
    email: "nut@host.invalid"
    id: "12112_4"
    name: "Message Role 1"
    rolename: "Bobby Barnes"
    templateId: 1111
    type: "template"
},
{
    association: "template"
    color: "(255, 12, 119, 0.35)"
    email: "rnaonew@host.invalid"
    id: "12112_4"
    name: "Messi"
    rolename: "Bobby Barnes"
    templateId: 9999
    type: "template"
}
]

Now, based on the templateId I would like to create a new Array of objects that uses templateId as key and has all data corresponding to that templateId's Object as separate objects as shown below:

Expected Result

    "users": {
        "8888": [
            {
                association: "template"
                color: "(255, 209, 0, 0.35)"
                email: "ehe@example.com"
                id: "12158_2"
                name: "sevderadebvu"
                rolename: "Floyd Phelps"
                type: "template"
            },
            {
                association: "template"
                color: "(0, 7, 255, 0.35)"
                email: "unoja@host.local"
                id: "12158_3"
                name: "ekdevajwirum"
                rolename: "Virginia Martin"
                type: "template"
            }
        ],
        "1111": [
        {
            association: "template"
            color: "(255, 121, 169, 0.35)"
            email: "nut@host.invalid"
            id: "12112_4"
            name: "Message Role 1"
            rolename: "Bobby Barnes"
            type: "template"
        },
    ],
    "9999": [
        {
            association: "template"
            color: "(255, 12, 119, 0.35)"
            email: "rnaonew@host.invalid"
            id: "12112_4"
            name: "Messi"
            rolename: "Bobby Barnes"
            type: "template"
        }
    ]
    }
} 

Ignore any missing key-value pairs (templateId removed from the expected result)

Yohanelly
  • 69
  • 1
  • 9
  • have you tried anything? what goes wrong? – Nina Scholz Sep 01 '20 at 11:26
  • I'm actually not sure how to even go about it @NinaScholz, any pointers for me to try out? – Yohanelly Sep 01 '20 at 11:30
  • https://stackoverflow.com/questions/40774697/how-to-group-an-array-of-objects-by-key/40774906#40774906 btw the question is a duplicate. – Nina Scholz Sep 01 '20 at 11:31
  • Oops, I can edit the question. It's not exactly the same, in my case I'd also like to add/remove certain key-value pairs from the expected result. Should I do this after the reduce function? – Yohanelly Sep 01 '20 at 11:36

1 Answers1

2

You can use the function Array.prototype.reduce for grouping by the templateId as follow:

const arr = [{    association: "template",    color: "(255, 209, 0, 0.35)",    email: "ehe@example.com",    id: "12158_2",    name: "sevderadebvu",    rolename: "Floyd Phelps",    templateId: 8888,    type: "template"},{    association: "template",    color: "(0, 7, 255, 0.35)",    email: "unoja@host.local",    id: "12158_3",    name: "ekdevajwirum",    rolename: "Virginia Martin",    templateId: 8888,    type: "template"},{    association: "template",    color: "(255, 121, 169, 0.35)",    email: "nut@host.invalid",    id: "12112_4",    name: "Message Role 1",    rolename: "Bobby Barnes",    templateId: 1111,    type: "template"},{    association: "template",    color: "(255, 12, 119, 0.35)",    email: "rnaonew@host.invalid",    id: "12112_4",    name: "Messi",    rolename: "Bobby Barnes",    templateId: 9999,    type: "template"}],
      skipKeys = ["templateId", "rolename"],
      groupingKey = "templateId",
      result = arr.reduce((r, c) => {
        let desiredObject = 
              Object.entries(c).filter(([key]) => !skipKeys.includes(key))
                    .reduce((a, [key, value]) => Object.assign(a, ({[key]: value})), {});
                    
        (r[c[groupingKey]] || (r[c[groupingKey]] = [])).push(desiredObject);
        return r;
      }, Object.create(null));

console.log(result);
Ele
  • 33,468
  • 7
  • 37
  • 75
  • Awesome this function does work, what if I want to add/delete certain key-value pairs in this reduce function? – Yohanelly Sep 01 '20 at 11:35
  • This worked, I had to make a few changes for my use case. But really cool stuff my guy. Thanks a million. – Yohanelly Sep 01 '20 at 14:14