0

I am looping over some object and updating the values of another based on some lookups, currently I have problems with getting the correct values in the mapping.

let users = [
  {
    "id": "123",
    "email": "[email protected]",
    "name": " John Doe",
    "group": "1",
    "subgroup": "1"
  },
  {
    "id": "456",
    "email": "[email protected]",
    "name": " Tom hans",
    "group": "2",
    "subgroup": "1"
  }
];

let groupData = [
  {
    id: "1",
    name: "Stars",
    subgroup: [
        {
          id: "1",
          pseudo: "big"
        },
        {
          id: "2",
          pseudo: "small"
        }
      ]
  },
  {
    id: "2",
    name: "Stones",
    subgroup: [
        {
          id: "1",
          pseudo: "tiny"
        },
        {
          id: "2",
          pseudo: "huge"
        }
      ]
  }
];

const allUsers = {};
for (var i = 0; i < users.length; i++) {
    let groupID = users[i].group,
        subgroupID = users[i].subgroup;

    users[i].group = users[i].group ? groupData[groupID][name] : '';
    users[i].subgroup = users[i].subgroup ?
        groupData[groupID].subgroup[subgroupID][name] : '';

    allUsers[users[i].id] = users[i];
}

The result of allUsers will look like:

{
  123: {
    "id": "123",
    "email": "[email protected]",
    "name": " John Doe",
    "group": "Stars",
    "subgroup": "big"
  },
  456: {
    "id": "456",
    "email": "[email protected]",
    "name": " Tom hans",
    "group": "Stones",
    "subgroup": "tiny"
  }
};

Currently, I have lookup problems inside my for loop to get the name of the group/subgroup.

Could somebody help to fix this issue? preferably with ecma6.

2 Answers 2

1

You're using groupData as if it's keys where the groupID. However, it's an array. You should try to use it's find method:

const allUsers = {};
for (var i = 0; i < users.length; i++) {
    let groupID = users[i].group,
        subgroupID = users[i].subgroup;
    let userGroup = groupData.find(group => group.id === groupID);

    users[i].group = userGroup.name
    users[i].subgroup = userGroup.subgroup.find(subgroup => subgroup.id === subgroupID).pseudo;

    allUsers[users[i].id] = users[i];
}

You are modifying your original data though, that's not necessary a good idea. You could create a new user in the loop and use Object.assign to avoid that.


Here's what I would do with only a reduce method:

const allUsers = users.reduce((data, user) => {
    const group = groupData.find(group => group.id === user.group);
    const name = group ? group.name : '';
    const subGroup = group ? group.subgroup.find(subgroup => subgroup.id === user.subgroup): null;
    const pseudo = subGroup ? subGroup.pseudo : '';
    data[user.group] = Object.assign({}, user, { group: name, subGroup: pseudo });
   return data;
}, {});

Object.assign creates a new object so it won't mutate the existing users.

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

6 Comments

how can the object assign be used in this example? and could we also replace that for loop with some mapping/filtering etc?
and what happens if a user doesnt have any group or subgroups? how can we pass ' ' empty value? I mean the group/subgroup field doesn't exist at all.
there is a syntax error in the last line... could you please have a look at it?
this second method is outputting undefined and only returning the first user with wrong data.
is this second code piece part of the first one ? or standalone?
|
1

You can use array#reduce to accumulate your user and use array#find to get the group name and subgroup pseudo name.

let users = [ { "id": "123", "email": "[email protected]", "name": " John Doe", "group": "1", "subgroup": "1" }, { "id": "456", "email": "[email protected]", "name": " Tom hans", "group": "2", "subgroup": "1" } ],
    groupData = [ { id: "1", name: "Stars",subgroup: [ { id: "1", pseudo: "big" }, { id: "2", pseudo: "small" } ] }, { id: "2", name: "Stones", subgroup: [ { id: "1", pseudo: "tiny" }, { id: "2", pseudo: "huge" } ] } ],
    result = users.reduce((r, user) => {
      var {name = '', subgroup = []} = groupData.find(o => o.id === user.group); 
      r[user.id] = Object.assign({}, user, {group: name}, {subgroup: subgroup.find(o => o.id === user.subgroup).pseudo||''});
      return r;
    }, {});
    
console.log(result);

2 Comments

what happens if a user doesn't have group field? but he has subgroup... basically it means, we can't return any value, so we should return empty for both.
Just update this line user.group && groupData.find(o => o.id === user.group);

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.