2

I have the following array, which has an object holding nested arrays that in turn have objects of their own:

var list = [{
    one: [{key: 1, value: 'eng1'}, {key: 2, value: 'eng2'}],
    two: [{key: 1, value: 'esp1'}, {key: 2, value: 'esp2'}]
}];

I want to group the data above by the key property inside the objects of the nested arrays. The following is the desired structure:

var grouped = [
    {
        key: 1,
        group: {
            one: {
                value: 'eng1'
            },
            two: {
                value: 'esp1'
            }
        }
    },
    {
        key: 2,
        group: {
            one: {
                value: 'eng2'
            },
            two: {
                value: 'esp2'
            }
        }
    }
]

I have tried so many ways to achieve the above structure but to no avail. I have tried using reduce but that was mainly applicable if the objects were not deeply nested. My problem is the fact that the arrays are nested inside the objects and the key is embedded in those objects. Your help would be greatly appreciated.

The requirement is to not use any library such as underscore or lodash. I have to get this working with plain JS.

2 Answers 2

3

You can use multiple forEach loops because of your data structure and add to new array.

var list = [{
    one: [{key: 1, value: 'eng1'}, {key: 2, value: 'eng2'}],
    two: [{key: 1, value: 'esp1'}, {key: 2, value: 'esp2'}]
}];

var grouped = [];
list.forEach(function(e) {
  Object.keys(e).forEach(function(k) {
    var that = this;
    e[k].forEach(function(a) {
      if(!that[a.key]) grouped.push(that[a.key] = {key: a.key, group: {}})
      Object.assign(that[a.key].group, {[k]: {value: a.value}})
    })
  }, {})
})

console.log(grouped)

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

3 Comments

Thanks Nenad, I was hoping to avoid a nested loop. But, I guess, that is not possible.
Your nested data structure necessitates nested processes. There are certainly other ways to do this, probably some involving reduce, but you won't get away from the nesting.
@pro Depending on your actual data structure maybe you can avoid first loop jsfiddle.net/Lg0wyt9u/2247
1

You may try for this:

var list = [{
    one: [{key: 1, value: 'eng1'}, {key: 2, value: 'eng2'}],
    two: [{key: 1, value: 'esp1'}, {key: 2, value: 'esp2'}]
}];

var grouped = [];
list.forEach(function(e) {
  Object.keys(e).forEach(function(k) {
    var that = this;
    e[k].forEach(function(a) {
      if(!that[a.key]) grouped.push(that[a.key] = {key: a.key, group: {}})
      Object.assign(that[a.key].group, {[k]: {value: a.value}})
    })
  }, {})
})

console.log(grouped)

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.