Сопоставить ключ вложенного объекта с другим ключом - PullRequest
0 голосов
/ 22 февраля 2019

Работая со следующим объектом, как можно добавить 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,
   })),
}));

Ответы [ 3 ]

0 голосов
/ 22 февраля 2019

Вы можете перебрать sites и обновить userPermission, используя find

(Предполагается, что каждый roleId существует в roles. В противном случае вынужно проверить, если find возвращает undefined сначала)

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.log(obj)
0 голосов
/ 22 февраля 2019

Вы можете сначала превратить массив 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.log(obj);
0 голосов
/ 22 февраля 2019

Создайте карту ролей:

 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,
};
...