#javascript
#javascript
Вопрос:
Мне нужно сгенерировать плоский массив объектов, содержащий всех предков данного объекта, в плоском нормализованном массиве объектов.
Существует множество примеров превращения его во вложенную древовидную структуру, но я не смог найти никакой информации для простого возврата всех предков в плоский массив. Каждый объект в плоском нормализованном массиве имеет идентификатор и родительский идентификатор.
Дан плоский нормализованный массив объектов
[
{
id: 1,
name: "node 1",
parentId: null,
}, {
id: 2,
name: "node 2",
parentId: 1,
}, {
id: 3,
name: "node 3",
parentId: null,
}, {
id: 4,
name: "node 4",
parentId: 3,
}, {
id: 5,
name: "node 5",
parentId: 2,
}, {
id: 6,
name: "node 6",
parentId: 1,
}, {
id: 7,
name: "node 7",
parentId: 6,
},
]
При выполнении getAncestors(1)
этого должны быть возвращены все предки узла 1
[
{
id: 2,
name: "node 2",
parentId: 1,
}, {
id: 5,
name: "node 5",
parentId: 2,
}, {
id: 6,
name: "node 6",
parentId: 1,
}, {
id: 7,
name: "node 7",
parentId: 6,
},
]
Я пытался модифицировать функции, чтобы превратить их во вложенную древовидную структуру, но безуспешно.
Комментарии:
1. вам все еще нужно дерево или, по крайней мере, стек. кстати, что вы пробовали?
2. Проблема не в том, чтобы сгенерировать вложенное дерево. Это очень просто, поскольку есть много примеров того, как это сделать. И, конечно, было бы тривиально впоследствии превратить его в плоский массив. Я надеялся на некоторую помощь в выполнении этого напрямую, поэтому мне не нужно сначала строить дерево, а затем обходить его, чтобы сгенерировать этот плоский массив.
Ответ №1:
Для доступа к фаастеру вам нужен файл a Map
со всеми узлами и их id
ключом as, а также карта для всех родителей с parentId
ключом as. Тогда вам нужна функция getAncestors
, а внутри вам нужна функция для получения nod и его предков.
Объедините все с уменьшением и верните результат.
function getAncestors(parentId) {
const getNode = node => [node, ...getAncestors(node.id)];
return (parents.get(parentId) || []).reduce((r, id) => [...r, ...getNode(nodes.get(id))], []);
}
var data = [{ id: 1, name: "node 1", parentId: null, }, { id: 2, name: "node 2", parentId: 1 }, { id: 3, name: "node 3", parentId: null }, { id: 4, name: "node 4", parentId: 3 }, { id: 5, name: "node 5", parentId: 2 }, { id: 6, name: "node 6", parentId: 1 }, { id: 7, name: "node 7", parentId: 6 }],
nodes = new Map(data.map(o => [o.id, o])),
parents = data.reduce((m, { id, parentId }) => m.set(parentId, [... (m.get(parentId) || []), id]), new Map);
console.log(getAncestors(1));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Комментарии:
1. Вау, потрясающе. Не могу поверить, сколько времени может потребоваться некоторым из нас, чтобы придумать такие алгоритмы. Gj. Было бы еще более удивительно, если бы вам не нужно было сопоставлять узлы и родительские элементы (или каким-то образом привязывать их к getAncestors), но это позволит выполнить работу. Джи-Джи!