Skip to content

Instantly share code, notes, and snippets.

@neftaly
Last active May 17, 2017 00:12
Show Gist options
  • Save neftaly/7c316cec08cee9621846 to your computer and use it in GitHub Desktop.
Save neftaly/7c316cec08cee9621846 to your computer and use it in GitHub Desktop.
parent pointer tree to map
import R from "ramda";
const stringize = value => typeof value === "number" ? value + "" : value;
const orphanIds = R.compose(
R.reduce((partial, pair) => [
...partial,
pair[0],
...orphanIds(pair[1].children)
], []),
R.toPairs()
);
// Update de-orphaned indices to reflect the location of their new parent
const updateOrphanIndices = (orphan, parentLocation) => indices => R.reduce(
(partial, id) => R.over(R.lensProp(id), R.compose(
R.concat(parentLocation),
R.update(0, "children")
), partial),
indices,
orphanIds(orphan)
);
// Convert parent-pointer-tree to map
const resolve = R.reduce((partial, update) => {
const id = stringize(update.id);
const parent = stringize(update.parent);
const {
orphans,
indices
} = partial;
const orphan = R.path([id, "children"], orphans) || {};
const entry = R.compose(
R.dissoc("parent"),
R.dissoc("id"),
R.assoc("children", orphan)
)(update);
const location = (parent === null) ? [] :
indices[parent] || ["orphans", parent];
return R.compose(
R.over(R.lensProp("indices"), updateOrphanIndices(orphan, location)), // Update orphan indices
R.dissocPath(["orphans", id ]), // Remove obsolete orphan entry
R.assocPath(["indices", id], [ ...location, "children", id ]), // Assign new index
R.assocPath([...location, "children", id], entry) // Attach to parent
)(partial);
});
const x = resolve({
children: {},
orphans: {},
indices: {}
}, [
{
id: 5,
x: "c5",
parent: 2
},
{
id: 1,
x: "a1",
parent: null
},
{
id: 2,
x: "b2",
parent: 1
},
{
id: 3,
x: "b3",
parent: 1
},
{
id: 4,
x: "c4",
parent: 2
}
]);
JSON.stringify(x, null, 4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment