Created
May 16, 2017 17:26
-
-
Save jasonkuhrt/11d892845a2fe0c321ba424c8fd643d0 to your computer and use it in GitHub Desktop.
menu-tree.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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