Skip to content

Instantly share code, notes, and snippets.

@jimthedev
Last active July 2, 2018 14:54
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 jimthedev/4fe3d5cafa1b9e22c5d99f6adea76366 to your computer and use it in GitHub Desktop.
Save jimthedev/4fe3d5cafa1b9e22c5d99f6adea76366 to your computer and use it in GitHub Desktop.
precalculate.tree
const expect = require("expect");
const nav = {
children: [
{
text: "Home",
link: "/home",
children: [
{
text: "About",
link: "/home/about",
children: [
{
text: "About/Our History",
link: "/home/about/history"
}
]
},
{
text: "mypeople/deep",
link: "/mypeople/deep",
children: [
{
text: "Jim",
link: "/person/jim"
},
{
text: "Ariana",
link: "/person/ariana"
}
]
}
]
},
{
text: "Products",
link: "/products",
children: [
{
text: "someproducts",
children: [
{
text: "Lawn Mower",
link: "/products/lawn-mower"
}
]
}
]
}
]
};
// Sanity check
expect(nav.children[0].link).toBe("/home");
expect(nav.children[1].link).toBe("/products");
/**
* Adds the link property of a node
* to that node's links array.
*/
const addOwnLinkToOwnLinks = node => {
if (node.link) {
const { links, ...restOfNode } = node;
if (links && typeof links !== undefined) {
return {
links: [node.link, ...links],
...restOfNode
};
}
return restOfNode;
}
return node;
};
const testNodeWithoutChildrenOrLinks = {
text: "Home Page",
link: "/home"
};
expect(
addOwnLinkToOwnLinks(testNodeWithoutChildrenOrLinks).links
).not.toBeDefined();
expect(addOwnLinkToOwnLinks(testNodeWithoutChildrenOrLinks).text).toEqual(
"Home Page"
);
expect(addOwnLinkToOwnLinks(testNodeWithoutChildrenOrLinks).link).toEqual(
"/home"
);
const testNodeWithoutChildren = {
text: "Home Page",
link: "/home",
links: ["/home/hi"]
};
expect(addOwnLinkToOwnLinks(testNodeWithoutChildren).links).toEqual(
expect.arrayContaining(["/home/hi"])
);
expect(addOwnLinkToOwnLinks(testNodeWithoutChildren).links).toEqual(
expect.arrayContaining(["/home"])
);
expect(addOwnLinkToOwnLinks(testNodeWithoutChildren).text).toEqual("Home Page");
expect(addOwnLinkToOwnLinks(testNodeWithoutChildren).link).toEqual("/home");
const testNode = {
text: "Home Page",
link: "/home",
links: ["/home/hi"]
};
expect(addOwnLinkToOwnLinks(testNode).links).toEqual(
expect.arrayContaining(["/home", "/home/hi"])
);
expect(addOwnLinkToOwnLinks(testNode).text).toEqual("Home Page");
expect(addOwnLinkToOwnLinks(testNode).link).toEqual("/home");
/**
* Add links, via breadth (reduce an array of nodes)
*/
const reduceLinks = nodes => {
if (!nodes || !nodes.reduce) {
return [];
}
return nodes.reduce((a, newChildNode) => {
const newChildLinks = addOwnLinkToOwnLinks(newChildNode).links;
if (newChildLinks) {
return a.concat(newChildLinks);
}
return a;
}, []);
};
expect(reduceLinks({ shouldBe: "array" }).length).toBe(0);
expect(reduceLinks([testNodeWithoutChildrenOrLinks]).length).toBe(0);
expect(reduceLinks([testNodeWithoutChildren]).length).toBe(2);
/**
* Recursively map over a node's children (depth)
*/
const makeSubLinks = aNode => {
if (!aNode.children) {
return aNode;
}
// Loop through all nodes
return aNode.children.map(({ children, ...node }) => {
// Turn a node into an ideal node
const nodeWithLinks = { links: [], ...node };
// Get the children, also include their sub links
const newChildren = makeSubLinks({
children,
...node
});
// Return the original node with its:
// - new links
// - children which also include sub links
return {
...node,
links: nodeWithLinks.links.concat(reduceLinks(newChildren)),
children: newChildren
};
});
};
const linkList = makeSubLinks(nav);
console.log(JSON.stringify(linkList));
// So to see if we should expand a given node, we simply use:
//
// if (node.links.indexOf(path) > -1 || node.link === path) {
// expandThisNode()
// }
//
// Please note that expandThisNode might just render an expanded node.
const result = [
{
text: "Home",
link: "/home",
links: [
"/home/about",
"/home/about/history",
"/mypeople/deep",
"/person/jim",
"/person/ariana"
],
children: [
{
text: "About",
link: "/home/about",
links: ["/home/about/history"],
children: [
{
text: "About/Our History",
link: "/home/about/history",
links: [],
children: { text: "About/Our History", link: "/home/about/history" }
}
]
},
{
text: "mypeople/deep",
link: "/mypeople/deep",
links: ["/person/jim", "/person/ariana"],
children: [
{
text: "Jim",
link: "/person/jim",
links: [],
children: { text: "Jim", link: "/person/jim" }
},
{
text: "Ariana",
link: "/person/ariana",
links: [],
children: { text: "Ariana", link: "/person/ariana" }
}
]
}
]
},
{
text: "Products",
link: "/products",
links: ["/products/lawn-mower"],
children: [
{
text: "someproducts",
links: ["/products/lawn-mower"],
children: [
{
text: "Lawn Mower",
link: "/products/lawn-mower",
links: [],
children: { text: "Lawn Mower", link: "/products/lawn-mower" }
}
]
}
]
}
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment