Reputation: 21452
I have a table in my database contain templates, that template consist of some fields like Carrier, Category
I need to group them by Carrier and under each Carrier I would like to group them by Category
here is my code where formatted
is the code that comes from the database
here is a sample of formatted
[{carrier:'carier1',category:'category1',name:'Value1' , ....}, {carrier:'carier1',category:'category1',name:'Value2'}, {carrier:'carier1',category:'category1',name:'Value3'}, {carrier:'carier1',category:'category2',name:'Value4'}, {carrier:'carier2',category:'category1',name:'Value5'}, {carrier:'carier2',category:'category1',name:'Value6'}];
here is my code
export interface TemplateList {
carrier?: string;
categories?: templateCategory[];
}
export interface templateCategory {
category?: string;
templates?: {};
}
import R from "ramda";
var templateList: TemplateList[] = [];
const byCarrier = R.groupBy((element: any) => {
return element.carrier;
});
const byCategory = R.groupBy((element: any) => {
return element.category;
});
var carriers = byCarrier(formatted);
Object.keys(carriers).forEach((element) => {
var item: TemplateList = {};
item.carrier = element;
var categories = byCategory(carriers[element]);
var templatelist: templateCategory[] = [];
Object.keys(categories).forEach((cat) => {
var templateCat: templateCategory = {};
templateCat.category = cat;
templateCat.templates = categories[cat];
templatelist.push(templateCat);
});
item.categories = templatelist;
templateList.push(item);
});
return { carriers: templateList };
expected data format
{"carriers": [
{
"carrier": "carrier1",
"categories": [
{
"category": "Misc",
"templates": [
{
"name": "name1",
"category": "Misc",
"carrier": "carrier1",
"body": "body1",
"subject": "subject",
"ticketResponseTemplateId": 235
}
]
}
]
},
{
"carrier": "carrier2",
"categories": [
{
"category": "Misc",
"templates": [
{
"name": "Aetna MS - Add State",
"category": "Misc",
"carrier": "carrier2",
"body": "<p>new body</p>",
"subject": "Aetna MS - Adding a State",
"ticketResponseTemplateId": 234
}
]
}
]
}
]
}
Upvotes: 0
Views: 361
Reputation: 643
I wrote a general function that you can apply to any level of group nesting you need and that would yield you the appropriate types, the function is the following
function groupBy<T, E>(array: T[], key: string, map: (group: T[], key: string) => E) {
const groups = array.reduce((acc, current) => {
(acc[current[key]] = acc[current[key]] || []).push(current);
return acc;
}, {});
return Object.keys(groups).map((group) => {
return map(groups[group], group);
})
}
For your example, you can use like this :
const grouped = groupBy<any, TemplateList>(response, 'carrier', (carrierList, carrier) => {
return {
carrier,
categories: groupBy<any, TemplateCategory>(carrierList, 'category', (categoryList, category) => {
return {
category,
templates: categoryList.map((v) => {
return {
name: v.name,
/* Any other projection in the final object */
};
})
};
})
}
})
Here is a working Stackblitz https://stackblitz.com/edit/typescript-defxxj
Upvotes: 1
Reputation: 642
check this, I tried to figure out the database query return
export interface TemplateList {
carrier?: string;
categories?: templateCategory[];
}
export interface templateCategory {
category?: string;
templates?: {};
}
var templateList: TemplateList[] = [];
var carriers = [{ carier: 'carier1', category: 'category1', template: 't1' },
{ carier: 'carier1', category: 'category1', template: 't2' },
{ carier: 'carier1', category: 'category1', template: 't3' },
{ carier: 'carier1', category: 'category2', template: 't4' },
{ carier: 'carier2', category: 'category1', template: 't5' },
{ carier: 'carier2', category: 'category1', template: 't6' }];
carriers.forEach((carier) => {
if (templateList?.length > 0) {
templateList.forEach(tempItem => {
if (tempItem.carrier == carier.carier) {
const tempCat: templateCategory = { category: carier.category, templates: carier.template };
tempItem.categories.push(tempCat);
}
else {
const tempCat: templateCategory = { category: carier.category, templates: carier.template };
templateList.push({ carrier: carier.carier, categories: [tempCat] })
}
}
);
} else {
const tempCat: templateCategory = { category: carier.category, templates: carier.template };
templateList.push({ carrier: carier.carier, categories: [tempCat] })
}
});
console.log({ carriers: templateList });
Upvotes: 1