I have 2 arrays one having the Group info and the other having Field info. I want to combine these 2 arrays to create proper Grouped Fields.
The API response looks like
{
"type1": [
{
"groupId": "1",
"fieldIds": [
"field1",
"field2"
]
},
{
"groupId": "2",
"fieldIds": [
"field3"
]
}
],
"type2": [
{
"groupId": "3",
"fieldIds": [
"field4",
"field5"
]
},
{
"groupId": "4",
"fieldIds": [
"field3"
]
}
],
"fields": [
{
"fieldId": "field1",
"fieldName": "FName1"
}...
]
}
I want to group fields so that the output looks like
{
"type1": [
{
"groupId": "1",
"fields": [
{
"fieldId": "field1",
"fieldName": "FName1"
},
{
"fieldId": "field2",
"fieldName": "FName2"
}
]
},
{
"groupId": "2",
"fields": [
{
"fieldId": "field3",
"fieldName": "FName3"
}
]
}
],
"type2": [
{
"groupId": "3",
"fields": [
{
"fieldId": "field4",
"fieldName": "FName4"
},
{
"fieldId": "field5",
"fieldName": "FName5"
}
]
}
]
}
I have accomplished the "brutal" way where I am traversing the groups, picking the fieldId, searching that fieldId in the fields array and then putting it under the group. It works but what I am looking is some "clean" way to do this using lodash chaining.
My approach is to group the fields by id and create a lookup object so I can directly access it in O(1).
Then transform the object to array of entries so I can iterate an replace the field ids with the actual fields. After that convert back to an object
first i will give the non lodash
const {fields, ...types} = { "type1": [ { "groupId": "1", "fieldIds": [ "field1", "field2" ] }, { "groupId": "2", "fieldIds": [ "field3" ] } ], "type2": [ { "groupId": "3", "fieldIds": [ "field4", "field5" ] }, { "groupId": "4", "fieldIds": [ "field3" ] } ], "fields": [ { "fieldId": "field1", "fieldName": "FName1" }, { "fieldId": "field2", "fieldName": "FName2" }, { "fieldId": "field3", "fieldName": "FName3" }, { "fieldId": "field4", "fieldName": "FName4" }, { "fieldId": "field5", "fieldName": "FName5" } ] }
const groupedFields = fields.reduce((acc,curr) => {
acc[curr.fieldId] = curr
return acc
},{})
const result = Object.fromEntries(Object.entries(types).map(([k,v]) => {
const newV = v.map(({groupId,fieldIds}) => {
const fields = fieldIds.map(fieldId => groupedFields[fieldId])
return {groupId,fields}
})
return [k,newV]
}))
console.log(JSON.parse(JSON.stringify(result)))
lodash solution
const {fields, ...types} = { "type1": [ { "groupId": "1", "fieldIds": [ "field1", "field2" ] }, { "groupId": "2", "fieldIds": [ "field3" ] } ], "type2": [ { "groupId": "3", "fieldIds": [ "field4", "field5" ] }, { "groupId": "4", "fieldIds": [ "field3" ] } ], "fields": [ { "fieldId": "field1", "fieldName": "FName1" }, { "fieldId": "field2", "fieldName": "FName2" }, { "fieldId": "field3", "fieldName": "FName3" }, { "fieldId": "field4", "fieldName": "FName4" }, { "fieldId": "field5", "fieldName": "FName5" } ] }
const groupedFields = _.groupBy(fields,'fieldId')
const result = _.mapValues(types, (value) => {
return _.map(value, ({ groupId, fieldIds }) => ({
groupId,
fields: _.map(fieldIds, (fieldId) => groupedFields[fieldId][0]),
}));
});
console.log(JSON.parse(JSON.stringify(result)))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>