0

I have a dictionary of arrays as follow:

var usersTemp = {11: [ {"active": true, "email": "seconduser@example.com", "userid": 2, } ],
            12:  [ {"active": true, "email": "firstuser@example.com", "userid": 1, },
                   {"active": true, "email": "seconduser@example.com", "userid": 2, } ], }

I need to merge the elements that have the same email address or userid and get something similar to this:

{ 1: {"active": true, "email": "firstuser@example.com", "roles": [12]} ,
  2: {"active": true, "email": "seconduser@example.com", "roles": [11 , 12]}, }

This is my try:

var mergedUsersTemp = {};
for (var role in usersTemp) {
    for (var user in usersTemp[role]) {
        if(!mergedUsersTemp[user]){
            const i = JSON.parse(JSON.stringify(usersTemp[role][user]));
            console.log(JSON.stringify(i))
            mergedUsersTemp[user] = {"active": i["active"], "email": i["email"], "id": i["id"], "roles": []};
            mergedUsersTemp[user]["roles"] = [];
        }
        mergedUsersTemp[user]["roles"].push(role);
    }
}

But the problem is deep copy in javascript and it's returning the same value for the user info. How can I fix it?

Andreas
  • 21,535
  • 7
  • 47
  • 56
Birish
  • 5,514
  • 5
  • 32
  • 51
  • whats your current output? – Jonas Wilms Mar 10 '17 at 16:04
  • @Jonasw I've replicated OP's current code [in this JSFiddle](https://jsfiddle.net/tr_santi/pnd69dro/). – Tyler Roper Mar 10 '17 at 16:06
  • `user` is the index in the array, not the user ID. Try `var uid = usersTemp[role][user]['userid'];` and use that in `if(!mergedUsersTemp[uid])` and so on. This seems to give the result you want. – Niet the Dark Absol Mar 10 '17 at 16:07
  • Don't use `for...in...` for an array: [Why is using “for…in” with array iteration a bad idea?](https://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-a-bad-idea). Not a problem here, but don't let it become a habit :) – Andreas Mar 10 '17 at 16:13
  • And what's with all the `JSON.parse(JSON.stringify(...))` lately? O.o – Andreas Mar 10 '17 at 16:14
  • If in result 1 and 2 are userid's then why 1 has 11 and 12, shouldn't it be the other way. – Nenad Vracar Mar 10 '17 at 16:20
  • @NenadVracar Based on the email addresses this was a typo on the ids – Andreas Mar 10 '17 at 16:25

1 Answers1

1

Instead of for...in loop its easier to use Object.keys() and forEach loop. Then you just need to first check if userid already exists in object and set its value or add to roles and change active.

var usersTemp = {
  11: [{
    "active": true,
    "email": "seconduser@example.com",
    "userid": 2,
  }],
  12: [{
    "active": true,
    "email": "firstuser@example.com",
    "userid": 1,
  }, {
    "active": true,
    "email": "seconduser@example.com",
    "userid": 2,
  }],
}

var result = {}
Object.keys(usersTemp).forEach(function(i) {
  usersTemp[i].forEach(function(j) {
    if (!result[j.userid]) {
      result[j.userid] = {
        active: j.active,
        email: j.email,
        roles: []
      }
    }
    result[j.userid].roles.push(i)
    result[j.userid].active = j.active
  })
})

console.log(result)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176