9years
9years

Reputation: 129

Sub-grouping array of objects inside of sub-array of main array

I have an array like this

[
    {
        "id": 1,
        "name": "Personal Information",
        "TabFields": [
            {
                "name": "First Name",
                "field": {
                    "code": "personFirstName"
                }
            },
            {
                "name": "Gender",
                "field": {
                    "code": "personGenderD"
                }
            },
            {
                "name": "Last Name",
                "field": {
                    "code": "personLastName"
                }
            },
            {
                "name": "Mobile Number",
                "field": {
                    "code": "mobileNumber"
                }
            },
            {
                "name": "Email Address",
                "field": {
                    "code": "emailAddress"
                }
            }
        ]
    }
]

What I need is to group the objects inside the TabFields to their respective TAB (PERSONAL_INFORMATION, CONTACT_DETAILS) by code value inside the field object

The object

"name": "First Name",
"field": {
    "code": "personFirstName"
}
"name": "Gender",
"field": {
    "code": "personGenderD"
}
"name": "Last Name",
"field": {
    "code": "personLastName"
}

is belong to PERSONAL_INFORMATION and the object

"name": "Mobile Number",
"field": {
    "code": "mobileNumber"
}
"name": "Email Address",
"field": {
    "code": "emailAddress"
}

is belong to CONTACT_DETAILS. So the output would be

[
    {
        "id": 1,
        "name": "Personal Information",
        "TabFields": [
            {
                "label": "PERSONAL_INFORMATION",
                "code": "PERSONAL_INFORMATION",
                "fields": [
                    {
                        "name": "First Name",
                        "field": {
                            "code": "personFirstName"
                        }
                    },
                    {
                        "name": "Gender",
                        "field": {
                            "code": "personGenderD"
                        }
                    },
                    {
                        "name": "Last Name",
                        "field": {
                            "code": "personLastName"
                        }
                    }
                ]
            },
            {
                "label": "CONTACT_DETAILS",
                "code": "PERSONAL_INFORMATION",
                "fields": [
                    {
                        "name": "Mobile Number",
                        "field": {
                            "code": "mobileNumber"
                        }
                    },
                    {
                        "name": "Email Address",
                        "field": {
                            "code": "emailAddress"
                        }
                    }
                ]
            }
        ]
    }
]

How to do it in javascript?

Upvotes: 0

Views: 73

Answers (2)

richytong
richytong

Reputation: 2462

You can express transformations simply with a library I created, rubico.

const { pipe, fork, assign, get, map, filter } = require('rubico')

const PERSONAL_INFORMATION_FIELDS = new Set(['First Name', 'Gender', 'Last Name'])

const CONTACT_DETAILS_FIELDS = new Set(['Mobile Number', 'Email Address'])

// [datum] => [datum_with_grouped_TabFields]
const groupTabFields = assign({ // reassign TabFields to new grouped TabFields
  TabFields: fork([
    fork({
      label: () => 'PERSONAL_INFORMATION',
      code: () => 'PERSONAL_INFORMATION',
      fields: pipe([
        get('TabFields'), // datum => datum.TabFields
        filter(pipe([ // FILTER: for each TabField of TabFields
          get('name'), // TabField => TabField.name
          field => PERSONAL_INFORMATION_FIELDS.has(field), // check if PERSONAL_INFORMATION_FIELDS has name
        ])),
      ]),
    }),
    fork({ // same as above but with contact details
      label: () => 'CONTACT_DETAILS',
      code: () => 'CONTACT_DETAILS',
      fields: pipe([
        get('TabFields'),
        filter(pipe([
          get('name'),
          field => CONTACT_DETAILS_FIELDS.has(field)
        ])),
      ]),
    }),
  ]),
})

x = map(groupTabFields)(data)

console.log(JSON.stringify(x, null, 2)) // output is what you wanted

I've added some comments, but for a deeper understanding of the library and code I've given you, I recommend reading the intuition and then reading the docs

Upvotes: 1

Rajneesh
Rajneesh

Reputation: 5308

You can also do this with map:

var arr=[ { "id": 1, "name": "Personal Information", "TabFields": [ { "name": "First Name", "field": { "code": "personFirstName" } }, { "name": "Gender", "field": { "code": "personGenderD" } }, { "name": "Last Name", "field": { "code": "personLastName" } }, { "name": "Mobile Number", "field": { "code": "mobileNumber" } }, { "name": "Email Address", "field": { "code": "emailAddress" } } ] }];

personalContact = ["Mobile Number", "Email Address"];

result = arr.map(val=>{
    personalInfo = { label:'personal', code:val.name, fields:val.TabFields.filter(k=>!personalContact.includes(k.name))};
    contactInfo = { label:'contact', code:val.name, fields:val.TabFields.filter(k=>personalContact.includes(k.name))};
    val.TabFields = [personalInfo, contactInfo];
    return val;
});

console.log(result);

Idea would be to have an array which should distinguish between the contact details and personal details using which you can apply filter to get the data.

Upvotes: 1

Related Questions