Home > Software engineering >  Sorting array based on nested object value in javascript
Sorting array based on nested object value in javascript

Time:08-30

I'm trying to sort/arrange array based on nested object value.

Current array :

const comments = [{
        "id": 1745,
        "bannerId": 35002,
        "content": "lorem ipsum",
        "user": "John Doe",
        "banner": {
          "format": "300x250",
          "lang": "EN"
        }
      },
      {
        "id": 1747,
        "bannerId": 35002,
        "content": "test 2222",
        "user": "John Doe",
        "banner": {
          "format": "300x250",
          "lang": "EN"
        }
      },
      {
        "id": 1750,
        "bannerId": 35002,
        "content": "test 3333",
        "user": "Frank Doe",
        "banner": {
          "format": "300x250",
          "lang": "EN"
        }
      },
      {
        "id": 1744,
        "bannerId": 35004,
        "content": "bla bla",
        "user": "John Doe",
        "banner": {
          "format": "300x600",
          "lang": "EN"
        }
      },
      {
        "id": 1746,
        "bannerId": 35006,
        "content": "tesssttt",
        "user": "Frank Doe",
        "banner": {
          "format": "970x250",
          "lang": "NL"
        }
      }];

I googled many documents for sorting nested object, but I couldn't find the way of my case and I struggled so many hours so I want to ask to how can I sort above array of objects.

Desired output (or something like this) :

const comments = [{
        "EN" : [{
          "300x250" : [{
            "John Doe" : [
              {"id": 1745, "bannerId": 35002, "comment": "lorem ipsum"},
              {"id": 1747, "bannerId": 35002, "comment": "test 2222"}
            ]
          },{
            "Frank Doe" : [
              {"id": 1750, "bannerId": 35002, "comment": "test 3333"}
            ]
          }]
        },{
          "300x600" : [{
            "John Doe" : [
              {"id": 1744, "bannerId": 35004, "comment": "bla bla"}
            ]
          }]
        }]
        },{
        "NL" : [{
          "970x250" : [{
            "Frank Doe" : [
              {"id": 1746, "bannerId": 35006, "comment": "tesssttt"}
            ]
          }]
        }]
      }];

I've already tried this without success :

let list = [];

      for (let i = 0; i < comments.length; i  ) {

        list[comments[i].banner.lang] = [{
          [comments[i].banner.format] : [{
            [comments[i].user] : [{
              'id': comments[i].id, 'bannerId': comments[i].bannerId, 'comments' : comments[i].content
            }]
          }]
        }];

      }

The "=" overwrite the previous data..
There is something i messed up but i can't figured out :s

Hope someone here can help me :)

CodePudding user response:

You could find the nested items of the grouping arrays.

This approach takes an array of functions for getting the right key value at the wanted level.

const 
    data = [{ id: 1745, bannerId: 35002, content: "lorem ipsum", user: "John Doe", banner: { format: "300x250", lang: "EN" } }, { id: 1747, bannerId: 35002, content: "test 2222", user: "John Doe", banner: { format: "300x250", lang: "EN" } }, { id: 1750, bannerId: 35002, content: "test 3333", user: "Frank Doe", banner: { format: "300x250", lang: "EN" } }, { id: 1744, bannerId: 35004, content: "bla bla", user: "John Doe", banner: { format: "300x600", lang: "EN" } }, { id: 1746, bannerId: 35006, content: "tesssttt", user: "Frank Doe", banner: { format: "970x250", lang: "NL" } }],
    groups = [o => o.banner.lang, o => o.banner.format, o => o.user],
    result = data.reduce((r, o) => {
        groups
            .reduce((a, fn) => {
                let key = fn(o),
                    p = a.find(q => key in q);

                 if (!p) a.push(p = { [key]: [] });
                 return p[key];
            }, r)
            .push({ id: o.id, bannerId: o.bannerId, comment: o.content });
        return r;
    }, []);

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

CodePudding user response:

let list = [];

for (let i = 0; i < comments.length; i  ) {
    if (!list[comments[i].banner.lang]) {
        list[comments[i].banner.lang] = [];
    }

    if (!list[comments[i].banner.lang][comments[i].banner.format]) {
        list[comments[i].banner.lang][comments[i].banner.format] = [];
    }

    if (!list[comments[i].banner.lang][comments[i].banner.format][comments[i].user]) {
        list[comments[i].banner.lang][comments[i].banner.format][comments[i].user] = [];
    }

    list[comments[i].banner.lang][comments[i].banner.format][comments[i].user].push({
          'id': comments[i].id, 
          'bannerId': comments[i].bannerId, 
          'comment' : comments[i].content
    });
}
  • Related