0

I have data like this :

users = [{
    "emp_id": 1,
    "user": {
        "emp_full_name": "Test",
        "emp_email": "test@gmail.com",
        "emp_phone_no": null,
        "preferred_work_type": null
    },
    "hashtag": {
        "id": 1,
        "name": "NodeJs",
        "hashtag_group_id": 1
    },
    "difficulty": "HARD"
}, {
    "emp_id": 2,
    "user": {
        "emp_full_name": "test2",
        "emp_email": "test2@gmail.com",
        "emp_phone_no": null,
        "preferred_work_type": null
    },
    "hashtag": {
        "id": 1,
        "name": "NodeJs",
        "hashtag_group_id": 1
    },
    "difficulty": "EASY"
}, {
    "emp_id": 1,
    "user": {
        "emp_full_name": "Test",
        "emp_email": "test@gmail.com",
        "emp_phone_no": null,
        "preferred_work_type": null
    },
    "hashtag": {
        "id": 4,
        "name": "Javascript",
        "hashtag_group_id": 1
    },
    "difficulty": "HARD"
}]

I want to add hashtag to same the object that has the same emp_id. If emp_id has more than one data then the data that has the emp_id with the single hashtag data should be removed.

So basically this is what I expected:

[{
    "emp_id": 1,
    "user": {
        "emp_full_name": "Test",
        "emp_email": "test@gmail.com",
        "emp_phone_no": null,
        "preferred_work_type": null
    },
    "hashtag": [{
        "id": 1,
        "name": "NodeJs",
        "hashtag_group_id": 1
    }, {
        "id": 4,
        "name": "Javascript",
        "hashtag_group_id": 1
    }],
    "difficulty": "HARD"
}, {
    "emp_id": 2,
    "user": {
        "emp_full_name": "test2",
        "emp_email": "test2@gmail.com",
        "emp_phone_no": null,
        "preferred_work_type": null
    },
    "hashtag": {
        "id": 1,
        "name": "NodeJs",
        "hashtag_group_id": 1
    },
    "difficulty": "EASY"
}]

How to transform the data like that?

I have no idea how to solve that, I tried using filter(), and map() with some validation condition, but couldn't get it to work.

trincot
  • 317,000
  • 35
  • 244
  • 286

2 Answers2

0

You could create a Map keyed by emp_id and collect the users by that key. When there is already an entry, extend the hashtag using [].concat. This will create an array if it wasn't an array yet.

const users = [{"emp_id": 1,"user": {"emp_full_name": "Test","emp_email": "test@gmail.com","emp_phone_no": null,"preferred_work_type": null},"hashtag": {"id": 1,"name": "NodeJs","hashtag_group_id": 1},"difficulty": "HARD"},{"emp_id": 2,"user": {"emp_full_name": "test2","emp_email": "test2@gmail.com","emp_phone_no": null,"preferred_work_type": null},"hashtag": {"id": 1,"name": "NodeJs","hashtag_group_id": 1},"difficulty": "EASY"},{"emp_id": 1,"user": {"emp_full_name": "Test","emp_email": "test@gmail.com","emp_phone_no": null,"preferred_work_type": null},"hashtag": {"id": 4,"name": "Javascript","hashtag_group_id": 1},"difficulty": "HARD"}];

const map = new Map;
for (const user of users) {
    const match = map.get(user.emp_id);
    if (match) match.hashtag = [].concat(match.hashtag, user.hashtag);
    else map.set(user.emp_id, {...user});
}
const result = [...map.values()];

console.log(result);
trincot
  • 317,000
  • 35
  • 244
  • 286
  • I already using your code but dont know why it's not working in mine. I already double checked the code – user18605090 May 18 '22 at 09:24
  • If you can post your code in a fiddle (like on jsfiddle.net), I could have a look at it. Please explain what exactly is going wrong. – trincot May 18 '22 at 09:25
  • I made a little update to avoid that the original objects are mutated. – trincot May 18 '22 at 09:27
  • was check in jsfiddle.net, it's work there. it's weird in my local doesn't work. let me check again – user18605090 May 18 '22 at 09:39
  • the data was correct when i try console.log(result[0].hashtag) it show the added hashtag, but when i return to response, res.status(200).json(result). it's showing 2 ids, but without the hashtag that already concat. What's the problem with that ? – user18605090 May 18 '22 at 09:57
  • actually the ```users``` was the result from querying database with sequelize – user18605090 May 18 '22 at 10:00
  • 1
    That is a different problem, and means your array is changing *after* it was retrieved. `console.log` is lazy and if you expand an array in the console, it will show data that was added *after* the `console.log` executed. See [Is Chrome’s JavaScript console lazy about evaluating objects?](https://stackoverflow.com/questions/4057440/is-chrome-s-javascript-console-lazy-about-evaluating-objects). For you it means you are triggering the conversion too soon, and need to await that later modification, which may happen asynchronously. But all this is unrelated to your question here. – trincot May 18 '22 at 10:07
0

You can use .reduce() with .findIndex(). Try this

let users = '[{"emp_id": 1, "user": {"emp_full_name": "Test", "emp_email": "test@gmail.com", "emp_phone_no": null, "preferred_work_type": null }, "hashtag": {"id": 1, "name": "NodeJs", "hashtag_group_id": 1 }, "difficulty": "HARD"}, {"emp_id": 2, "user": {"emp_full_name": "test2", "emp_email": "test2@gmail.com", "emp_phone_no": null, "preferred_work_type": null }, "hashtag": {"id": 1, "name": "NodeJs", "hashtag_group_id": 1 }, "difficulty": "EASY"}, {"emp_id": 1, "user": {"emp_full_name": "Test", "emp_email": "test@gmail.com", "emp_phone_no": null, "preferred_work_type": null }, "hashtag": {"id": 4, "name": "Javascript", "hashtag_group_id": 1 }, "difficulty": "HARD"} ]';
users = JSON.parse(users)

users = users.reduce((arr, o) => {
    let idx = arr.findIndex(({emp_id}) => emp_id === o.emp_id);
    if( idx !== -1 ) arr[idx].hashtag = [].concat(arr[idx].hashtag, o.hashtag)
    else arr.push(o)

    return arr;
}, []);

console.log(users)
ruleboy21
  • 5,510
  • 4
  • 17
  • 34
  • i was using your code but still have problem that i mention in other answer comment – user18605090 May 18 '22 at 10:02
  • @user18605090 it seems you response is a JSON string. You have to convert it to an array using `JSON.parse()`. I've updated my answer kindly check it out – ruleboy21 May 18 '22 at 10:54