Nithin Benny
Nithin Benny

Reputation: 142

Format the input array , The result should be a grouped array in the below given format in Angular

Format the input array , The result should be a grouped array

This is the input Array:

let INPUT_DATA: Object[] = [
    {
        id: 1,
        'a-level': "World",
        'b-level': "Asia",
        'c-level': "",
        'd-level': "",
    },
    {
        id: 2,
        'a-level': "World",
        'b-level': "Asia",
        'c-level': "India",
        'd-level': "",
    },
    {
        id: 3,
        'a-level': "World",
        'b-level': "Asia",
        'c-level': "India",
        'd-level': "Kerala",
    },
    {
        id: 4,
        'a-level': "World",
        'b-level': "Europe",
        'c-level': "",
        'd-level': "",
    },
    {
        id: 5,
        'a-level': "World",
        'b-level': "Europe",
        'c-level': "Italy",
        'd-level': "",
    },
    {
        id: 6,
        'a-level': "World",
        'b-level': "Europe",
        'c-level': "Germany",
        'd-level': "",
    },
    {
        id: 7,
        'a-level': "Day",
        'b-level': "",
        'c-level': "",
        'd-level': "",
    }
    {
        id: 8,
        'a-level': "Day",
        'b-level': "Hour",
        'c-level': "",
        'd-level': "",
    },
    {
        id: 9,
        'a-level': "Day",
        'b-level': "Hour",
        'c-level': "Minute",
        'd-level': "",
    }
];

The output array is a grouped version of the input array.In the input array there are 4 a -level entry that is "world" , But in the output array the world is grouped as one and all the elements inside it is also grouped.

This is the output Array:

let OUTPUT_DATA: Object[] = [
    {
        id: ",
        indexName: 'World',
        subIndexLevels: [
            { 
                id: 1, 
                indexName: 'Asia',
                subIndexLevels: [
                    { 
                        id: 2, 
                        indexName: 'India',
                        subIndexLevels: [
                            { 
                                id: 3, 
                                indexName: 'Kerala',
                            }
                        ]
                    }
                ]
            },
            { 
                id: 4, 
                indexName: 'Europe',
                subIndexLevels: [
                    { 
                        id: 5, 
                        indexName: 'Italy',
                    },
                    { 
                        id: 6, 
                        indexName: 'Germany',
                    }
                ]
            }
        ]
    },
    {
        id: 7,
        indexName: 'Day',
        subIndexLevels: [
            { 
                id: 8, 
                indexName: 'Hour',
                subIndexLevels: [
                    { 
                        id: 9, 
                        indexName: 'Minute',
                    }
                ]
            }
        ]
    },
]

Upvotes: 2

Views: 157

Answers (3)

Nina Scholz
Nina Scholz

Reputation: 386560

You could take a dynamic approach and filter the names for the levels and seach for it in every level.

If not found, create a new object for the level.

At the end assign id to the latest object.

var data = [{ id: 1, "a-level": "World", "b-level": "Asia" }, { id: 2, "a-level": "World", "b-level": "Asia" }, { id: 2, "a-level": "World", "b-level": "Asia", "c-level": "India" }, { id: 3, "a-level": "World", "b-level": "Asia", "c-level": "India", "d-level": "Kerala" }, { id: 4, "a-level": "World", "b-level": "Europe" }, { id: 5, "a-level": "World", "b-level": "Europe", "c-level": "Italy" }, { id: 6, "a-level": "World", "b-level": "Europe", "c-level": "Germany" }, { id: 7, "a-level": "Day" }, { id: 8, "a-level": "Day", "b-level": "Hour" }, { id: 9, "a-level": "Day", "b-level": "Hour", "c-level": "Minute"}],
    keys = ["a-level", "b-level", "c-level", "d-level"],
    result = data.reduce((r, o) => {
        var target = keys.map(k => o[k])
                .filter(Boolean)
                .reduce((level, indexName) => {
                    var temp = (level.subIndexLevels = level.subIndexLevels || [])
                            .find(q => q.indexName === indexName);

                    if (!temp) level.subIndexLevels.push(temp = { id: '', indexName });
                    return temp;
                }, { subIndexLevels: r });

            target.id = target.id
                ? target.id + ',' + o.id
                : o.id;
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 5

Adrita Sharma
Adrita Sharma

Reputation: 22213

Try like this:

Working Demo

  constructor() {
    var aLevelDistinctData = this.GetDistinctValues(this.INPUT_DATA, "a-level");

    aLevelDistinctData.forEach(a_item => {
      var asubIndexLevels = [];
      var a_itemSubLevels = this.INPUT_DATA.filter(x => x["a-level"] == a_item["a-level"]);
      var bLevelDistinctData = this.GetDistinctValues(a_itemSubLevels, "b-level");
      bLevelDistinctData = bLevelDistinctData.filter(x => x["b-level"] != "");

      bLevelDistinctData.forEach(b_item => {
        var bsubIndexLevels = [];
        var b_itemSubLevels = a_itemSubLevels.filter(x => x["b-level"] == b_item["b-level"] && b_item["a-level"] == a_item["a-level"]);

        var csubIndexLevels = [];

        var cLevelDistinctData = this.GetDistinctValues(b_itemSubLevels, "c-level");
        cLevelDistinctData = cLevelDistinctData.filter(x => x["c-level"] != "");
        cLevelDistinctData.forEach(c_item => {
          var c_itemSubLevels = b_itemSubLevels.filter(x => x["c-level"] == c_item["c-level"] && c_item["b-level"] == b_item["b-level"]);

          var dLevelDistinctData = this.GetDistinctValues(c_itemSubLevels, "d-level");
          dLevelDistinctData = dLevelDistinctData.filter(x => x["d-level"] != "");

          dLevelDistinctData.forEach(d_item => {
            csubIndexLevels.push({
              id: d_item["id"],
              indexName: d_item["d-level"]
            });
          });

          bsubIndexLevels.push({
            id: c_item["id"],
            indexName: c_item["c-level"],
            subIndexLevels: [...csubIndexLevels]
          });
        });

        asubIndexLevels.push({
          id: b_item["id"],
          indexName: b_item["b-level"],
          subIndexLevels: [...bsubIndexLevels]
        });
      });

      this.OUTPUT_DATA.push({
        id: a_item["id"],
        indexName: a_item["a-level"],
        subIndexLevels: [...asubIndexLevels]
      });
    });

    console.log(this.OUTPUT_DATA);
  }

  GetDistinctValues(Source: Array<any>, FilterKey: string = null): Array<any> {
    let DistinctArray = [];
    try {
      Source.forEach(e => {
        if (FilterKey !== null && FilterKey !== undefined && FilterKey !== "") {
          if (
            DistinctArray.filter(DE => DE[FilterKey] === e[FilterKey]).length <=
            0
          )
            DistinctArray.push(e);
        } else {
          if (DistinctArray.indexOf(e) === -1) DistinctArray.push(e);
        }
      });
    } catch (error) {
      DistinctArray = [];
    }
    return DistinctArray;
  }

Note: You can take this idea and refactor it further.

Upvotes: 2

Allabakash
Allabakash

Reputation: 2027

Checkout this Library , This provides good options for grouping nested elements. https://github.com/danrevah/ngx-pipes#groupby

Upvotes: 0

Related Questions