Составить дерево с сгенерированным ключем обозначения уровня вложенности из плоского массива
Вопросов, как мой уже наверно было задано достаточное количество. Но я все равно хочу попросить помощи. Необходимо составить дерево из плоского массива. (Вся задача на React). Пример массива и выполнение ниже.
Объекты у которых есть ключ group-id, будут ребенками(вложенными), соответственно объекты у которых этого ключа нет, будут являться корневыми. Какой размерности приходящий массив и какая будет вложенность не известно. Погуглив я нашел инфу\функцию listToTree(), которую немного адаптировал под себя:
const data = [{
"name": "test-sub-sub-sub-1",
"id": "0309a88c-9fe2-4099-b4fd-d73778992bf6",
"owner": "user65",
"group-id": "0923e178-2545-4c72-98f0-f4f1269fcb91",
"all_connected": false,
"min_occupancy": 0
},
{
"name": "group-09:29:11",
"id": "08024e3b-310d-4fb7-857f-2402835ea074",
"owner": "user65",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "test-sub-1-sub",
"id": "0923e178-2545-4c72-98f0-f4f1269fcb91",
"owner": "user65",
"group-id": "d5a87a40-1a8f-473f-a1be-cfbfa8cdeea9",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "test-request",
"id": "0965811f-169a-4d79-8763-93726bba242e",
"owner": "user65",
"group-id": "test",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "220989test",
"id": "1b12cf14-6ae6-43c7-a6aa-8472b7f6182c",
"owner": "user65",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "test-sub-2",
"id": "24036394-a869-40e4-ad13-26aa136ecab0",
"owner": "user65",
"group-id": "test",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "sub-18:07:08",
"id": "3ec62bcf-f068-40b7-aa4a-ab7ad4c688bb",
"owner": "user65",
"group-id": "test",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "kossSubSubTest",
"id": "55e2f468-4877-4772-9758-9ac7eb510f7e",
"owner": "user65",
"group-id": "08024e3b-310d-4fb7-857f-2402835ea074",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "test-sub",
"id": "5e4d01bf-47b3-4cc6-8ae3-acdd7e7e69f4",
"owner": "user65",
"group-id": "test",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "sub-18:00:08",
"id": "67d22ca4-6904-446d-81f8-04e30337475a",
"owner": "user65",
"group-id": "a4fb3a47-5e81-4371-b710-c7bb403d6cc1",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "test-sub-2-sub",
"id": "6c426312-445d-4127-8294-2eea8bccacf7",
"owner": "user65",
"group-id": "24036394-a869-40e4-ad13-26aa136ecab0",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "group-17:58:20",
"id": "a4fb3a47-5e81-4371-b710-c7bb403d6cc1",
"owner": "user65",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "09:30:12sub",
"id": "a8067d6e-f7af-4bfd-8725-57a784febf5a",
"owner": "user65",
"group-id": "08024e3b-310d-4fb7-857f-2402835ea074",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "subTestSub",
"id": "ac6ac836-776a-48e0-a31b-a23a72e4352e",
"owner": "user65",
"group-id": "44827731-4107-48c6-8f1a-6d2451122721",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "17:36:33sub",
"id": "b8a3508a-9cc9-40e8-a34d-880005468582",
"owner": "user65",
"group-id": "1b12cf14-6ae6-43c7-a6aa-8472b7f6182c",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "220989test-sub",
"id": "c1c5a8e6-4c45-4aa0-bb77-d710b3e51cc8",
"owner": "user65",
"group-id": "1b12cf14-6ae6-43c7-a6aa-8472b7f6182c",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "test-sub-sub",
"id": "c813dc70-eddf-4c8c-8040-f193cbc1cd65",
"owner": "user65",
"group-id": "5e4d01bf-47b3-4cc6-8ae3-acdd7e7e69f4",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "test-sub-sub-sub",
"id": "d49d99cb-9bb6-4c01-85a3-31c2964b0563",
"owner": "user65",
"group-id": "c813dc70-eddf-4c8c-8040-f193cbc1cd65",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "test-sub-1",
"id": "d5a87a40-1a8f-473f-a1be-cfbfa8cdeea9",
"owner": "user65",
"group-id": "test",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "test-sub-sub-sub-2",
"id": "d8db6b11-74a1-4db9-8c6e-f6b13cfa02d1",
"owner": "user65",
"group-id": "6c426312-445d-4127-8294-2eea8bccacf7",
"all_connected": true,
"min_occupancy": 0
},
{
"name": "newSubSubSub",
"id": "fadf1d12-7a0f-44f9-9690-7e0dda58f709",
"owner": "user65",
"group-id": "0309a88c-9fe2-4099-b4fd-d73778992bf6",
"all_connected": true,
"min_occupancy": 0
},
]
function listToTree(data, options) {
options = options || {};
let ID_KEY = options.idKey || "id";
let PARENT_KEY = options.parentKey || "group-id";
let CHILDREN_KEY = options.childrenKey || "children";
let tree = {};
let childrenOf = {};
let item, id, parentId;
for (let i = 0, length = data.length; i < length; i++) {
item = data[i];
id = item[ID_KEY];
parentId = item[PARENT_KEY] || null;
childrenOf[id] = childrenOf[id] || {};
const object = {
name: item.name,
id: item.id,
label: item.name,
value: item.name.toLocaleLowerCase(),
parentId: parentId,
};
object[CHILDREN_KEY] = childrenOf[id];
if (parentId) {
childrenOf[parentId] = childrenOf[parentId] || {};
childrenOf[parentId][id] = object;
} else {
tree[id] = object;
}
}
console.log(tree);
return tree;
}
listToTree(data)
group, на втором уровне subgroup, на третьем уровне device. Или можно как-нибудь динамически генерировать ключ типа level1, level2... leveln. Для чего мне это нужно: На странице у меня есть селекты, при выборе элемента из первого уровеня у меня добавляется новый селект с чилдренами:
Так же при изменении селектов у меня меняется роут и подгружается новый компонент. Массив с роутами:
const routes = [
{
id: 1,
path: "/",
component: HomePage,
},
{
id: 2,
path: "/group/:id",
component: GroupContentPage,
},
{
id: 3,
path: "/group/:id/device/:id",
component: DeviceContentPage,
},
{
id: 4,
path: "*",
component: ErrorPage,
},
];
Вот мне и нужно сделать как-то новый ключ в дереве с названием уровня, чтобы я мог как-то за это зацепиться и сделать роут при onChange селекта. Я извиняюсь, что загрузил Вас таким большим описанием, но старался раскрыть задачу более конкретно. Заранее спасибо!
