Skip to content

Instantly share code, notes, and snippets.

@jasonkuhrt
Created May 16, 2017 17:26
Show Gist options
  • Save jasonkuhrt/11d892845a2fe0c321ba424c8fd643d0 to your computer and use it in GitHub Desktop.
Save jasonkuhrt/11d892845a2fe0c321ba424c8fd643d0 to your computer and use it in GitHub Desktop.
menu-tree.js
const F = require("lodash/fp")
const util = require("util")
const log = x => console.log(util.inspect(x, { colors: true, depth: null }))
log.step = () => console.log("============================================")
const Tree = {
createLeaf: value => ({ trunk: null, value }),
appendLeaf: (leaf, tree) => {
if (!tree.branches) tree.branches = []
leaf.trunk = tree
tree.branches.push(leaf)
return tree
},
get: (path, tree) => path.reduce((node, i) => node.branches[i], tree),
}
const catsMap = {
1: {
parentId: null,
// children: [{ id: 10 }, { id: 30 }],
},
2: {
parentId: null,
// children: [{ id: 20 }],
},
10: {
parentId: 1,
// children: [{ id: 100 }, { id: 400 }],
},
20: {
parentId: 2,
// children: [{ id: 200 }],
},
200: {
parentId: 20,
},
300: {
parentId: 30,
},
100: {
parentId: 10,
},
400: {
parentId: 10,
},
}
log(catsMap)
log.step()
const catsByParent = F.compose(
F.groupBy(cat => cat.parentId || "root"),
F.map(([id, cat]) => Object.assign(cat, { id })),
F.entries
)(catsMap)
log(catsByParent)
log.step()
const catsMapToTree = catsByParent => {
const tree = Tree.createLeaf()
catsByParent.root.forEach(cat, i => {
const leaf = Tree.createLeaf(cat)
Tree.appendLeaf(leaf, tree)
catsByParent[cat.id].forEach(childCat => {
Tree.appendLeaf(Tree.createLeaf(cat), leaf)
})
})
return tree
}
const menuTree = catsMapToTree(catsByParent)
log(menuTree)
log.step()
// const tree = Tree.createLeaf({ id: 1 })
// log(tree)
// Tree.appendLeaf(Tree.createLeaf({ id: 2 }), tree)
// log(tree)
// const menuTree = {
// trunk: null,
// branches: [
// {
// value: { id: 1 },
// trunk: null,
// branch: [
// {
// value: { id: 10 },
// trunk: 1,
// branch: [
// {
// value: { id: 100 },
// trunk: 10,
// },
// {
// value: { id: 400 },
// trunk: 10,
// },
// ],
// },
// {
// value: { id: 30 },
// trunk: 1,
// branch: [
// {
// value: { id: 300 },
// trunk: 30,
// },
// ],
// },
// ],
// },
// {
// value: { id: 2 },
// trunk: null,
// branch: [
// {
// value: { id: 20 },
// trunk: 2,
// branch: [
// {
// value: { id: 200 },
// trunk: 20,
// },
// ],
// },
// ],
// },
// ],
// }
const facets = [1, 2, 3, 4, 5, 6, 10, 20, 200, 30, 400]
// Functions
const mapTree = (tree, f) =>
tree.forEach((node, i) => {
tree[i] = f(node)
if (node.branch) mapTree(node.branch, f)
})
const filterTree = (tree, whitelist, newList = []) => {
tree.forEach((node, index) => {
if (!whitelist.includes(node.value.id)) {
// Delete the node from the tree if said node's ID is not in whitelist
tree[index] = null
} else if (node.branch) {
// Recurse until leaf
filterTree(node.branch, whitelist)
}
})
return tree
}
// log(menuTree)
// log("=============================")
// mapTree(menuTree, node =>
// Object.assign(node.value, { display: facets.includes(node.value.id) })
// )
// log(menuTree)
// filterTree(menuTree, facets)
// log(menuTree)
// CLIENT SIDE
const get = (path, object) =>
path.reduce((obj, segment) => obj[segment], object)
const mapAncestors = (f, tree) => {
if (!tree.trunk) return
f(tree.value)
mapAncestors(tree.trunk)
}
// const previousPath = []
// const currentPath = []
// const currentTree = get(currentPath, menuTree)
//
// log(get(currentPath, menuTree))
const tester = node => Object.assign(node, { HELLO: "WORLD" })
// mapAncestors(tester, menuTree)
// log(menuTree)
// renderTree((tree) => {
// <a>tree.value.name</a>
// if (tree.branch && tree.value.isOpen) {
// <div>
// renderTree(tree.branch)
// </div>
// }
// })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment