0

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 };

enter image description here

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
                                }
                            ]
                        }
                    ]
                }
            ]
        }
2
  • is your database query retrun looks like [{carierName:'carier1',categoryName:'category1',value:'Value1'}, {carierName:'carier1',categoryName:'category1',value:'Value2'}, {carierName:'carier1',categoryName:'category1',value:'Value3'}, {carierName:'carier1',categoryName:'category2',value:'Value4'}, {carierName:'carier2',categoryName:'category1',value:'Value5'}, {carierName:'carier2',categoryName:'category1',value:'Value6'}]; Commented Aug 3, 2020 at 21:55
  • yes Adam I will update my question to include how its looks like Commented Aug 3, 2020 at 22:00

2 Answers 2

1

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 });
Sign up to request clarification or add additional context in comments.

Comments

1
+50

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.