Как найти реквизиты вложенных объектов в массиве JavaScript? - PullRequest
0 голосов
/ 24 марта 2020

У меня есть массив объектов, который выглядит примерно так:

const roles = [
  {
    "id": "833ffe3d-cc24-4157-966c-5f8ceb856f4e",
    "hidden": false,
    "modified": "2020-03-20T15:14:12.689Z",
    "label": "Solution 2",
    "shortname": "Solution 2",
    "description": "Solution 2 description",
    "className": "Solution",
    "children": [
      {
        "id": "f1708329-eb9f-4042-bbe7-cdd1ff41b1b7",
        "hidden": false,
        "modified": "2020-03-20T15:14:12.293Z",
        "label": "USER CUSTOM ROLE",
        "displayName": "USER CUSTOM ROLE DISPLAY NAME",
        "className": "Role"
      }
    ]
  },
  {
    "id": "1a36709f-4de2-4f93-bf8e-57811d36e9f3",
    "hidden": false,
    "modified": "2020-03-20T15:14:12.668Z",
    "label": "Solution 1",
    "shortname": "Solution 1",
    "description": "Solution 1 description",
    "className": "Solution",
    "children": [
      {
        "id": "e824afbd-8b19-4363-b6fa-dd604f445cef",
        "hidden": false,
        "modified": "2020-03-20T15:14:12.271Z",
        "label": "USER ROLE",
        "displayName": "USER ROLE DISPLAY NAME",
        "className": "Role"
      },
      {
        "id": "8f2600d0-5328-4d41-8270-2eb10541860f",
        "hidden": false,
        "modified": "2020-03-20T15:14:12.095Z",
        "label": "BASE LOGIN ROLE",
        "displayName": "DISPLAY NAME - BASE LOGIN ROLE",
        "className": "Role"
      },
      {
        "id": "a14ce471-b792-4a5d-95ad-b9abb5dbe45c",
        "hidden": false,
        "modified": "2020-03-20T15:14:12.102Z",
        "label": "ORGANIZATION GLOBAL ROLE",
        "displayName": "DISPLAY NAME - GLOBAL ROLE",
        "className": "Role"
      },
      {
        "id": "d4a7d6ac-1663-48be-9fed-ce2a908f28f1",
        "hidden": false,
        "modified": "2020-03-20T15:14:12.130Z",
        "label": "DEPARTMENT 1 ROLE",
        "className": "Role"
      }
    ]
  }
];

Меня беспокоит id , label и children из этих объектов. Как видите, некоторые из объектов ролей содержат собственный массив ролей. И у меня есть еще один массив выбранных ролей, который выглядит следующим образом:

const selected = ["Solution 1", "USER ROLE", "DEPARTMENT 1 ROLE"];

Я хочу создать плоский массив идентификаторов, соответствующих выбранным ролям, например, для этого выбранного массива это будет (порядок не важно):

const result = ["d4a7d6ac-1663-48be-9fed-ce2a908f28f1", "e824afbd-8b19-4363-b6fa-dd604f445cef", "1a36709f-4de2-4f93-bf8e-57811d36e9f3"];

Итак, мой алгоритм в псевдокоде: 1. Проверьте root объект уровня. 2. Если его метка находится в выбранном массиве, pu sh это идентификатор массива результатов. 3. Если у него есть детская опора, проверьте всех его детей на одинаковое состояние. 4. Повторите эти действия для всех других объектов.

Мне удалось придумать только очень вонючую функцию, и она все еще не решает проблему вложенных ролей. Моя функция:

function getIds(arr, names) {
  let result = [];

  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < names.length; j++) {
      if (arr[i].label == names[j]) {
        result.push(arr[i].id);
      }
      if (arr[i].children) {
        for (let k = 0; k < arr[i].children.length; k++) {
          if (arr[i].children[k].label == names[j]) {
            result.push(arr[i].children[k].id);
          }
        }
      }
    }
  }

  return result;
}

Я знаю, что есть гораздо более чистые и красивые решения, я просто не могу придумать одно. Вы можете помочь?

1 Ответ

1 голос
/ 24 марта 2020

Сначала я бы сгладил массив с ролями, используя .flatMap(). Затем просто с помощью .map() сопоставьте метки с элементами массива и верните идентификаторы.

Попробуйте выполнить следующее:

const selected = ["Solution 1", "USER ROLE", "DEPARTMENT 1 ROLE"];
const roles = [{ "id": "833ffe3d-cc24-4157-966c-5f8ceb856f4e", "hidden": false, "modified": "2020-03-20T15:14:12.689Z",        "label": "Solution 2",        "shortname": "Solution 2",        "description": "Solution 2 description",        "className": "Solution",        "children": [{            "id": "f1708329-eb9f-4042-bbe7-cdd1ff41b1b7",            "hidden": false,            "modified": "2020-03-20T15:14:12.293Z",            "label": "USER CUSTOM ROLE",            "displayName": "USER CUSTOM ROLE DISPLAY NAME",            "className": "Role"          }        ]      },      {        "id": "1a36709f-4de2-4f93-bf8e-57811d36e9f3",        "hidden": false,        "modified": "2020-03-20T15:14:12.668Z",        "label": "Solution 1",        "shortname": "Solution 1",        "description": "Solution 1 description",        "className": "Solution",        "children": [{            "id": "e824afbd-8b19-4363-b6fa-dd604f445cef",            "hidden": false,            "modified": "2020-03-20T15:14:12.271Z",            "label": "USER ROLE",            "displayName": "USER ROLE DISPLAY NAME",            "className": "Role"          },          {            "id": "8f2600d0-5328-4d41-8270-2eb10541860f",            "hidden": false,            "modified": "2020-03-20T15:14:12.095Z",            "label": "BASE LOGIN ROLE",            "displayName": "DISPLAY NAME - BASE LOGIN ROLE",            "className": "Role"          },          {            "id": "a14ce471-b792-4a5d-95ad-b9abb5dbe45c",            "hidden": false,            "modified": "2020-03-20T15:14:12.102Z",            "label": "ORGANIZATION GLOBAL ROLE",            "displayName": "DISPLAY NAME - GLOBAL ROLE",            "className": "Role"          },          {            "id": "d4a7d6ac-1663-48be-9fed-ce2a908f28f1",            "hidden": false,            "modified": "2020-03-20T15:14:12.130Z",            "label": "DEPARTMENT 1 ROLE",            "className": "Role"          }        ]      }    ];

const flat = roles.flatMap(e => e.children.concat(e));
const result = selected.map(e => flat.find(f => f.label === e).id);

console.log(selected);
console.log(result);

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...