1

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 :)

2
  • Check if the sub array is already exists. If so - append to it the object, else create it. Commented Aug 30, 2022 at 9:54
  • btw, why do you want only a single key for nested grouping? Commented Aug 30, 2022 at 9:56

2 Answers 2

1

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((level, fn) => {
                let key = fn(o),
                    p = level.find(q => key in q);

                 if (!p) level.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; }

Sign up to request clarification or add additional context in comments.

1 Comment

Wow! so fast and exactly what i want.. Thanks a lot!!!
0
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
    });
}

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.