Skip to content

Instantly share code, notes, and snippets.

@stepan-anokhin
Last active October 31, 2019 04:28
Show Gist options
  • Save stepan-anokhin/5dc9049b50681584807ddc0bad8b113b to your computer and use it in GitHub Desktop.
Save stepan-anokhin/5dc9049b50681584807ddc0bad8b113b to your computer and use it in GitHub Desktop.
GraphTar
function containsRefs(array) {
return array.length > 0 && (array[0] instanceof Object);
}
function makeRecord(node, records) {
if (records.has(node)) {
return records.get(node);
}
const record = {
attrs: {},
refs: {},
id: records.size
};
records.set(node, record);
for (let key in node) {
const value = node[key];
if (value instanceof Array && containsRefs(value)) {
const array = [];
for (let obj of value) {
array.push(makeRecord(obj, records).id);
}
record.refs[key] = array;
} else if (value instanceof Object) {
record.refs[key] = makeRecord(value, records).id;
} else {
record.attrs[key] = value;
}
}
return record;
}
function tar(node) {
const records = new Map();
const archive = {
nodes: {}
};
const root = makeRecord(node, records);
archive.root = root.id;
for (let record of records.values()) {
archive.nodes[record.id] = record;
delete record.id;
}
return archive;
}
function untar(archive) {
const nodes = {};
for (let id in archive.nodes) {
nodes[id] = archive.nodes[id].attrs;
}
for (let id in archive.nodes) {
const node = nodes[id];
const record = archive.nodes[id];
for (let attr_name in record.refs) {
const ref = record.refs[attr_name];
if (ref instanceof Array) {
const array = [];
for (let item_ref of ref) {
const referent = nodes[item_ref];
array.push(referent);
}
node[attr_name] = array;
} else {
node[attr_name] = nodes[ref];
}
}
}
return nodes[archive.root];
}
const vasya = {name: "vasya", age: 25};
const petya = {name: "petya", age: 35};
const tolya = {name: "tolya", age: 17};
vasya.self = vasya;
vasya.friends = [petya, tolya];
petya.friends = [vasya, tolya];
tolya.friends = [vasya, petya];
let archive = tar(vasya);
console.log(JSON.stringify(archive));
vasya2 = untar(archive);
console.log(vasya2);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment