consider this array of object:
const relatedSites = [
{
"SubdomainName": "client1",
"ClientName": "Eastern Region",
"ClientAlias": "eastern-region"
},
{
"SubdomainName": "client1",
"ClientName": "City of Knox",
"ClientAlias": "knox"
},
{
"SubdomainName": "client2",
"ClientName": "Eastern Region",
"ClientAlias": "eastern-region"
},
{
"SubdomainName": "client2",
"ClientName": "City of Knox",
"ClientAlias": "knox"
}
]
I want to group these by the "SubdomainName" property and return an array of newly made objects using reduce so I get that result:
[
{
"title": "client1",
"links": [
{
"url": "https://client1.com/eastern-region",
"displayText": "Eastern Region"
},
{
"url": "https://client1.com/knox",
"displayText": "City of Knox"
}
]
},
{
"title": "client2",
"links": [
{
"url": "https://client2.com/eastern-region",
"displayText": "Eastern Region"
},
{
"url": "https://client2.com/knox",
"displayText": "City of Knox"
}
]
}
]
So far this is my solution but I think it looks a bit clunky, is there a more efficient way of doing it? I'm not liking the way I create a new group if I don't find it by title, also pushing the group to the array based on whether its index is found doesn't feel neat. Is there a more elegant way of achieving the same result?
const groupRelatedSites = (groups, item) => {
const group = groups.find(gp => gp.title === item.SubdomainName) || { title: item.SubdomainName, links: [] };
const index = groups.findIndex(group => group.title === item.SubdomainName);
const link = { url: `https://${item.SubdomainName}.com/${item.ClientAlias}`, displayText: item.ClientName };
group.links = [...group.links, link];
if (index === -1) {
groups.push(group);
} else {
groups[index] = group;
}
return groups;
};
const grouped = relatedSites.reduce(groupRelatedSites, []);