Reputation: 49
I have this object
users : [
{
_id: "5",
name: "tomek"
},
{
_id: "6",
name: "janek"
},
{
_id: "7",
name: "Jakub"
},
{
_id: "8",
name: "Piotr"
}
],
groups : [
{
users: ["5", "6"],
_id: "22",
name: "group 1"
},
{
users: ["7"],
_id: "33",
name: "group 2"
}
]
}
and I would like to modify it, that he looked like this
group:[{name:'group 1',user:[{objects with users belonging to the first group },{...},{...}]}, {name:'group 2',users:[{obj with users belonging to the first group},{...}]},{name:'no group'
,users:[{
objects with users not belonging to any group}]}
}
based on the above object, I would like to do one, Users without group should be thrown into group:'NO GROUP",
Upvotes: 1
Views: 198
Reputation: 1221
A little more old school...
<script>
var people = { users : [
{
_id: "5",
name: "tomek"
},
{
_id: "6",
name: "janek"
},
{
_id: "7",
name: "Jakub"
},
{
_id: "8",
name: "Piotr"
}
],
groups : [
{
users: ["5", "6", "12"],
_id: "22",
name: "group 1"
},
{
users: ["7"],
_id: "33",
name: "group 2"
}
]
}
var newgroups = []
var notfoundusers = []
for (var g=0; g<people.groups.length; g++)
{
var users = []
for (var u=0; u<people.groups[g].users.length; u++)
{
var p = people.users.find( x => x._id == people.groups[g].users[u] )
if ( p != undefined )
{
users.push(p);
}
else
{
notfoundusers.push( { group: people.groups[g].name, user: people.groups[g].users[u] } );
}
}
var group = { name: people.groups[g].name, user: users}
newgroups.push(group);
}
var notfoundgroup = { name: "no group", user: notfoundusers}
newgroups.push(notfoundgroup)
console.log(JSON.stringify(newgroups))
</script>
Upvotes: 0
Reputation: 301
Use ES6 map/reduce/filter/find array functions, for example :
// Your input
const input={users:[{_id:"5",name:"tomek"},{_id:"6",name:"janek"},{_id:"7",name:"Jakub"},{_id:"8",name:"Piotr"}],groups:[{users:["5","6"],_id:"22",name:"group 1"},{users:["7"],_id:"33",name:"group 2"}]};
// List all users in a group
const usersInGroup = input.groups.reduce((acc, g) => [...acc, ...g.users], []);
// Final "groups" Array
const groups = [
...input.groups.map(g => ({
name: g.name,
users: g.users.map((user) => input.users.find(u => u._id === user))
})),
{
name: 'NO GROUP',
users: input.users.filter(u => !usersInGroup.includes(u._id))
}
];
// Display groups
console.log(JSON.stringify(groups, null, ' '));
Upvotes: 1
Reputation: 3536
You can do this with a few iterations (map, filter, etc.) and create a new object or array. Play around with it a bit.
const data = {
users: [
{
_id: '5',
name: 'tomek',
},
{
_id: '6',
name: 'janek',
},
{
_id: '7',
name: 'Jakub',
},
{
_id: '8',
name: 'Piotr',
},
],
groups: [
{
users: ['5', '6'],
_id: '22',
name: 'group 1',
},
{
users: ['7'],
_id: '33',
name: 'group 2',
},
],
};
// Pack all groups and users together in "one" command
const result = [
// spread operator to spread the groups
...data.groups.map((group) => ({
// spread the group properties, you can also specify them individually
...group,
// find users with id
users: group.users.map((id) => data.users.find((user) => id === user._id)),
})),
// add a special group
{
name: 'NO_GROUP',
// filter the users
users: data.users.filter(
(user) =>
// check if user is not part of a group
!data.groups
.map((group) => group.users)
// flat() turns [["5", "6"], ["7"]] into ["5", "6", "7"]
.flat()
.includes(user._id)
),
},
];
console.log(result);
Upvotes: 1