0

im working on django rest and angular this json array is comming from server ic contain category and subCategory values.. im trying to build a dynamic navbar so i want to arrange this data like [ [web development] : ["subCat1","subcat2",....] [android development] : ["subCat1","subcat2",....] ] to access category and its related subctegory

i tried somthing like this : but it set only keys and value are empety

  public categories = [[], [], [], []];
  public data;
      for (let i = 0; i < this.data.length; i++) {


        if (this.data[i].cat_id != null) {
          this.categories[i][this.data[i].title] = [];


        }
        if (this.data[i].parent_id != null && this.data[i].parent_id == this.data[i].cat_id) {
          this.categories[i][this.data[i].title] = [this.data[i].title]
        }


      }

its server response

  [
        {
            "id": 5,
            "cat_id": 0,
            "parent_id": null,
            "title": "web development"
        },
        {
            "id": 6,
            "cat_id": 1,
            "parent_id": null,
            "title": "android development"
        },
        {
            "id": 7,
            "cat_id": null,
            "parent_id": 0,
            "title": "php"
        },
        {
            "id": 8,
            "cat_id": null,
            "parent_id": 1,
            "title": "java"
        }
    ]
devmrh
  • 1,171
  • 4
  • 19
  • 46
  • Possible duplicate of [What is the most efficient method to groupby on a JavaScript array of objects?](https://stackoverflow.com/questions/14446511/what-is-the-most-efficient-method-to-groupby-on-a-javascript-array-of-objects) – Heretic Monkey Mar 14 '18 at 15:28

2 Answers2

1

Here is a bit of code with does what you want:

interface Categories {
    [title: string]: string[]
}

let categories: Categories = {};

data.filter(c => c.parent_id === null).map(c => <{ title: string; subcategories: string[] }>{
    title: c.title,
    subcategories: data.filter(sc => sc.parent_id === c.cat_id).map(sc => sc.title)
}).forEach(c => {
    categories[c.title] = c.subcategories;
});

console.log(categories);

As you see, I define an interface. Then I create a temporal array with objects containing a title and its subcategories. Afterwards, I flatten that structure turning it into what you need.

The output is:

{
    "web development": ["php"],
    "android development": ["java"]
}
Oscar Paz
  • 18,084
  • 3
  • 27
  • 42
0

I don't know if I understand you correctly. I assume that the "data" variable contains the JSON and that the expected output would be:

{
    "web development": ["php"],
    "android development": ["java"]
}

This could be achieved by first creating a "categories" object, this object will be used to get a "title" for a given "parent_id".

const categories = data.reduce((acc, d) => {
    if (d.parent_id === null) {
        acc[d.cat_id] = d.title
    }

    return acc;
}, {});

Then create the stucture with

const structure = {};

data.forEach((d) => {
    if (d.parent_id === null) {
        structure[d.title] = [];
    } else {
        structure[categories[d.parent_id]].push(d.title);
    }
});

Structure now contains the data as I described earlier.