Работая со следующим объектом, как можно добавить roles => name к объекту sites => userPermission с соответствующим roleId?
Например, ключ userPermission первой записи sites будет обновлен до:
"userPermission": {
"roleId": 6,
"roleName": "Field Representative"
}
После сопоставления ключа roleName больше нет необходимости в массиве roles, и его можно удалить из конечного результата, как показано в ожидаемом результате.
const obj = {
"id": 542,
"createdAt": "2018-12-06T22:34:12.553Z",
"sites": [
{
"id": 10,
"siteId": "sixtysixone",
"edition": "pro",
"userPermission": {
"roleId": 6
}
},
{
"id": 2,
"siteId": "amplify",
"edition": "pro",
"userPermission": {
"roleId": 4
}
}
],
"roles": [
{
"id": 6,
"name": "Field Representative"
},
{
"id": 4,
"name": "Program Manager"
}
]
};
Ожидаемый результат:
const outcome = {
"id": 542,
"createdAt": "2018-12-06T22:34:12.553Z",
"sites": [
{
"id": 10,
"siteId": "sixtysixone",
"edition": "pro",
"userPermission": {
"roleId": 6,
"roleName": "Field Representative"
}
},
{
"id": 2,
"siteId": "amplify",
"edition": "pro",
"userPermission": {
"roleId": 4
"roleName": "Program Manager"
}
}
]
};
Я попытался использовать комбинацию .map и .find, но чувствую, что есть гораздо более простой/удобочитаемый способ сделать это.
const outcome = obj.map(o => ({
...o,
sites: o.sites
.map(s => ({
...s,
roleName: o.roles
.find(r => r.id === s.roleId).name,
})),
}));
Я не думаю, что вы можете map объект.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Создайте карту ролей:
const roles = new Map(obj.roles.map(({ id, name }) => [id, { roleId: id, roleName: name }]));
Тогда вы можете просто посмотреть:
const outcome = {
...obj,
sites: obj.sites.map(site => ({
...site,
userPermission: roles.get(site.userPermission.roleId),
}),
roles: undefined,
};
Вы можете перебрать sites и обновить userPermission, используя find
(Это предполагает, что каждый roleId существует в roles. В противном случае вам нужно сначала проверить, возвращает ли findundefined)
const obj = {"id":542,"createdAt":"2018-12-06T22:34:12.553Z","sites":[{"id":10,"siteId":"sixtysixone","edition":"pro","userPermission":{"roleId":6}},{"id":2,"siteId":"amplify","edition":"pro","userPermission":{"roleId":4}}],"roles":[{"id":6,"name":"Field Representative"},{"id":4,"name":"Program Manager"}]};
obj.sites.forEach(site => {
site.userPermission.roleName =
obj.roles.find(r => r.id === site.userPermission.roleId).name
})
delete obj.roles;
console.info(obj)Вы можете сначала превратить массив roles в объект, чтобы упростить поиск имен ролей:
let rolesMap = obj.roles.reduce((acc, role) =>
(acc[role.id] = role.name, acc),
Object.create(null)
);
Затем просто переберите массив сайтов, добавив свойство roleName к каждому объекту сайта userPermission, выбрав значение из rolesMap:
obj.sites.forEach(site => {
if (rolesMap[site.userPermission.roleId]) {
site.userPermission.roleName = rolesMap[site.userPermission.roleId];
}
});
Вы можете пропустить тест if, если точно знаете, что каждый объект сайта будет иметь связанный с ним объект роли в массиве roles. И если вы хотите создать новый объект sites, используйте map вместо forEach.
И, наконец, вы можете delete свойство roles, если хотите:
delete obj.roles;
Пример:
const obj = {"id":542,"createdAt":"2018-12-06T22:34:12.553Z","sites":[{"id":10,"siteId":"sixtysixone","edition":"pro","userPermission":{"roleId":6}},{"id":2,"siteId":"amplify","edition":"pro","userPermission":{"roleId":4}}],"roles":[{"id":6,"name":"Field Representative"},{"id":4,"name":"Program Manager"}]};
let rolesMap = obj.roles.reduce((acc, role) =>
(acc[role.id] = role.name, acc),
Object.create(null)
);
obj.sites.forEach(site => {
if (rolesMap[site.userPermission.roleId]) {
site.userPermission.roleName = rolesMap[site.userPermission.roleId];
}
});
delete obj.roles;
console.info(obj);
Что вы пробовали до сих пор, чтобы решить вашу проблему?