Skip to content

Instantly share code, notes, and snippets.

@papinianus
Created May 10, 2021 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save papinianus/2cef925eacdf5221536711cc078ea1e6 to your computer and use it in GitHub Desktop.
Save papinianus/2cef925eacdf5221536711cc078ea1e6 to your computer and use it in GitHub Desktop.
treefy chapter index
// Of https://twitter.com/suin/status/1390626681547751429
interface Chapter {
level: number;
text: string;
}
interface ChapterNode extends Chapter {
children: ChapterNode[];
}
const input = [
{ level: 1, text: "1章" },
{ level: 1, text: "2章" },
{ level: 2, text: "2.1" },
{ level: 2, text: "2.2" },
{ level: 1, text: "第3章" },
{ level: 2, text: "3.1" },
{ level: 2, text: "3.2" },
{ level: 3, text: "3.2.1" },
{ level: 3, text: "3.2.2" },
];
const treefy = (queue: Chapter[], level = 1): ChapterNode[] =>
queue.reduce(
(acc, cur, idx, array) =>
cur.level === level
? acc.concat({
...cur,
children: treefy(
takeWhile((c) => c.level >= level + 1, array.slice(idx + 1)),
level + 1
),
})
: acc,
[] as ChapterNode[]
);
const takeWhile = <T>(func: (head: T) => boolean, accum: T[]): T[] =>
accum.length && func(accum[0])
? [accum[0], ...takeWhile(func, accum.slice(1))]
: ([] as T[]);
console.log(JSON.stringify(treefy(input), null, 2));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment