1

I have below dynamic nested JSON object arrays and I wanted to get the desired output with JavaScript grouped by id from both.

First Array:

[
  {
    "id": "11",
    "name": "emp1",
    "location": [
      { "name": "abc", "id": "lc1" }
    ]
  },
  {
    "id": "11",
    "name": "emp2",
    "location": [
      { "name": "abc", "id": "lc1" },

    ]
  },
  {
    "id": "22",
    "name": "emp3",
    "location": [
      { "name": "xyz", "id": "lc2" }
    ]
  }
]

Second array like below.

[
  {
    "name": "sub1",
    "id": "11"
    ...
  },
  {
    "name": "sub1.1",
    "id": "11"
    ...
  },
  {
    "name": "sub2",
    "id": "22"
    ...
  }
]

Desired Output:

[
  {
    "id": "11",
    "first": [{"name": "emp1"},
              {"name": "emp2"}],
    "second": [{"name": "sub1"},{"name": "sub1.1"}],
    "location": [{"name": "abc"}]
  },
  {
    "id": "22",
    "first": [{"name": "emp3"}],
    "second": [{"name": "sub2"}],
    "location": [{"name": "xyz"}]
  }
]

How to get the desired output like above using javascript/angularjs?

2
  • does there only 2 properties in second array? Commented Mar 1, 2018 at 5:42
  • There are more but I only need those 2 elements in my output Commented Mar 1, 2018 at 5:48

2 Answers 2

2

I would do it using the amazing Array#reduce function.

Note that I have named your first array as a1, second as a2 and result as res.

a1.reduce(function(arr, obj) {
  var existing = arr.filter(function(res) {
    return res.id === obj.id
  })[0]
  if (existing) {
    existing.first.push({
      name: obj.name
    })
  } else {
    var second = a2.filter(function(res) {
      return res.id === obj.id
    })

    var secondObj = second.length ? second.map(function(sec) {
      return {
        name: sec.name
      };
    }) : []

    arr.push({
      id: obj.id,
      first: [{
        name: obj.name
      }],
      second: secondObj,
      location: obj.location
    })
  }

  return arr;
}, [])

Here's the working snippet. Take a look!

var a1 = [{
    "id": "11",
    "name": "emp1",
    "location": [{
      "name": "abc",
      "id": "lc1"
    }]
  },
  {
    "id": "11",
    "name": "emp2",
    "location": [{
      "name": "abc",
      "id": "lc1"
    }]
  },
  {
    "id": "22",
    "name": "emp3",
    "location": [{
      "name": "xyz",
      "id": "lc2"
    }]
  }
]

var a2 = [{
    "name": "sub1",
    "id": "11"
  }, {
    "name": "sub1.1",
    "id": "11"
  },
  {
    "name": "sub2",
    "id": "22"
  }
]

var res = a1.reduce(function(arr, obj) {
  var existing = arr.filter(function(res) {
    return res.id === obj.id
  })[0]
  if (existing) {
    existing.first.push({
      name: obj.name
    })
  } else {
    var second = a2.filter(function(res) {
      return res.id === obj.id
    })

    var secondObj = second.length ? second.map(function(sec) {
      return {
        name: sec.name
      };
    }) : []

    arr.push({
      id: obj.id,
      first: [{
        name: obj.name
      }],
      second: secondObj,
      location: obj.location
    })
  }

  return arr;
}, [])

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

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

3 Comments

I am using ECMA 2015. Also I am having large list of Ids in both arrays. Can you please post the updated code for ECMA 2015?
Also @tanmay, It doesn't get the names from second grouped by Ids if there are more than 1. Can you please check the edited question?
Hi @tanmay! Are you able to fix it if there are more in second based on the updated question?
0

var red1 = [{
    "id": "11",
    "name": "emp1",
    "location": [{
      "name": "abc",
      "id": "lc1"
    }]
  },
  {
    "id": "11",
    "name": "emp2",
    "location": [{
      "name": "abc",
      "id": "lc1"
    }]
  },
  {
    "id": "22",
    "name": "emp3",
    "location": [{
      "name": "xyz",
      "id": "lc2"
    }]
  }
]
var b = [{
    "name": "sub1",
    "id": "11"
  },
  {
    "name": "sub2",
    "id": "22"
  }
]
var identication = {}
var result = []
red1.forEach(function(val) {
  if (val['id'] in identication) {
    var t = {}
    t['name'] = val['name']
    result[identication[val['id']]]['first'].push(t)
  } else {
    var t = {}
    t['name'] = val['name']
    val['first'] = []
    val['first'].push(t)
    delete val['name']
    var identity = result.push(val)
    identication[val['id']] = identity - 1;
  }
})
b.forEach(function(d) {
  if (d['id'] in identication) {
    var t = {
      'name': d['name']
    }
    if (!('second' in result[identication[d['id']]])) {
      result[identication[d['id']]]['second'] = []
    }
    result[identication[d['id']]]['second'].push(t)
  } else {
    var t = {}
    for (key in d) {
      if (key == 'name')
        continue
      t[key] = d[key]
    }
    t['second'] = [{
      'name': d['name']
    }]
    var identity = result.push(t)
    identication[d['id']] = identity - 1;
  }
})
console.log(result)

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.