export interface HierarchyNode { id: string | null; title: string | null; children: Hierarchy | null; } export type Hierarchy = Record; function addToHierarchy( tree: Hierarchy, [noteId, title]: [string, string], ): Hierarchy { const path = noteId.split("/"); if (path.length === 0 || path[0] === "") { return tree; } // Create a dummy node to start the loop since the Hierarchy root is not a node. let curr: HierarchyNode = { id: null, title: null, children: tree }; for (const node of path) { // Capitalize first letter const nodeName = node.charAt(0).toUpperCase() + node.slice(1); curr.children ||= {}; if (!curr.children[nodeName]) { curr.children[nodeName] = { id: null, title: null, children: null }; } curr = curr.children[nodeName]; } curr.id = noteId; curr.title = title; return tree; } export function makeHierarchy(notes: Array<[string, string]>): Hierarchy { return notes.reduce(addToHierarchy, {}); }