问题
I didn't find any fast algorithm for getting quad-trees differences in following format. Let's say that we have two arbitrary 4 level trees:
var tree1 = [
{ id: "1.1", children: [
{ id: "1.1.1", children: null },
{ id: "1.1.2", children: null },
{ id: "1.1.3", children: [
{ id: "1.1.3.1", children: null },
{ id: "1.1.3.2", children: null },
{ id: "1.1.3.3", children: null },
{ id: "1.1.3.4", children: null }
] },
{ id: "1.1.4", children: null }
] },
{ id: "1.2", children: null },
{ id: "1.3", children: [
{ id: "1.3.1", children: [
{ id: "1.3.1.1", children: null },
{ id: "1.3.1.2", children: null },
{ id: "1.3.1.3", children: null },
{ id: "1.3.1.4", children: null }
] },
{ id: "1.3.2", children: null },
{ id: "1.3.3", children: null },
{ id: "1.3.4", children: null }
] },
{ id: "1.4", children: null }
];
var tree2 = [
{ id: "1.1", children: [
{ id: "1.1.1", children: null },
{ id: "1.1.2", children: null },
{ id: "1.1.3", children: null },
{ id: "1.1.4", children: [
{ id: "1.1.4.1", children: null },
{ id: "1.1.4.2", children: null },
{ id: "1.1.4.3", children: null },
{ id: "1.1.4.4", children: null }
] }
] },
{ id: "1.2", children: [
{ id: "1.2.1", children: null },
{ id: "1.2.2", children: null },
{ id: "1.2.3", children: [
{ id: "1.2.3.1", children: null },
{ id: "1.2.3.2", children: null },
{ id: "1.2.3.3", children: null },
{ id: "1.2.3.4", children: null }
] },
{ id: "1.2.1", children: null }
]},
{ id: "1.3", children: null },
{ id: "1.4", children: [
{ id: "1.4.1", children: [
{ id: "1.4.1.1", children: null },
{ id: "1.4.1.2", children: null },
{ id: "1.4.1.3", children: null },
{ id: "1.4.1.4", children: null }
] },
{ id: "1.4.2", children: null },
{ id: "1.4.3", children: null },
{ id: "1.4.1", children: null }
] }
];
So, I need to find differences and return them as:
var result = {
"1.1.3.1" : "1.1.3",
"1.1.3.2" : "1.1.3",
"1.1.3.3" : "1.1.3",
"1.1.3.4" : "1.1.3",
"1.1.4" : ["1.1.4.1", "1.1.4.2", "1.1.4.3", "1.1.4.4"],
"1.2" : ["1.2.1", "1.2.2". ["1.2.3.1", "1.2.3.2", "1.2.3.3", "1.2.3.4"], "1.2.4"],
"1.3.1.1" : "1.3",
"1.3.1.2" : "1.3",
"1.3.1.3" : "1.3",
"1.3.1.4" : "1.3",
"1.3.2" : "1.3",
"1.3.3" : "1.3",
"1.3.4" : "1.3",
"1.4" : [["1.4.1.1", "1.4.1.2", "1.4.1.3", "1.4.1.4"], "1.4.2", "1.4.3", "1.4.4"]
};
If you can see, the result has to be a map or a dictionary corresponding to updates. Didn't know how to reference ["1.1.3.1", "1.1.3.2", "1.1.3.3", "1.1.3.4"] to a single index, so I have split them, however if there is a more elegant way, you're welcome.
This data was created manually, so sorry if there're some mistakes.
回答1:
You could build a tree where you add a marker where
for adding/deleting a part of the tree and get from this the difference.
function getDifference(t1, t2) {
function getD(object, parent) {
function getKeys({ where, ...object }) {
return Object.keys(object).flatMap(k => [k, ...(object[k] ? getKeys(object[k]) : [])]);
}
var types;
Object
.entries(object)
.forEach(([k, { where, ...o }]) => {
if (where) {
let keys = getKeys(o);
if (!types) types = {};
if (!types[where]) types[where] = [];
types[where].push(keys.length ? [k, keys] : k);
} else {
getD(o, k);
}
});
if (types) {
if (-1 in types) result.push([types[-1], parent]);
if (1 in types) result.push([parent, types[1]]);
}
}
var temp = {},
add = (inc, tree) => ({ id, children }) => {
tree[id] = tree[id] || { where: 0 };
tree[id].where += inc;
if (children) children.forEach(add(inc, tree[id]));
},
result = [];
t1.forEach(add(-1, temp));
t2.forEach(add(1, temp));
getD(temp);
return result;
}
var tree1 = [{ id: "1.1", children: [{ id: "1.1.1", children: null }, { id: "1.1.2", children: null }, { id: "1.1.3", children: [{ id: "1.1.3.1", children: null }, { id: "1.1.3.2", children: null }, { id: "1.1.3.3", children: null }, { id: "1.1.3.4", children: null }] }, { id: "1.1.4", children: null }] }, { id: "1.2", children: null }, { id: "1.3", children: [{ id: "1.3.1", children: [{ id: "1.3.1.1", children: null }, { id: "1.3.1.2", children: null }, { id: "1.3.1.3", children: null }, { id: "1.3.1.4", children: null }] }, { id: "1.3.2", children: null }, { id: "1.3.3", children: null }, { id: "1.3.4", children: null }] }, { id: "1.4", children: null }],
tree2 = [{ id: "1.1", children: [{ id: "1.1.1", children: null }, { id: "1.1.2", children: null }, { id: "1.1.3", children: null }, { id: "1.1.4", children: [{ id: "1.1.4.1", children: null }, { id: "1.1.4.2", children: null }, { id: "1.1.4.3", children: null }, { id: "1.1.4.4", children: null }] }] }, { id: "1.2", children: [{ id: "1.2.1", children: null }, { id: "1.2.2", children: null }, { id: "1.2.3", children: [{ id: "1.2.3.1", children: null }, { id: "1.2.3.2", children: null }, { id: "1.2.3.3", children: null }, { id: "1.2.3.4", children: null }] }, { id: "1.2.4", children: null }] }, { id: "1.3", children: null }, { id: "1.4", children: [{ id: "1.4.1", children: [{ id: "1.4.1.1", children: null }, { id: "1.4.1.2", children: null }, { id: "1.4.1.3", children: null }, { id: "1.4.1.4", children: null }] }, { id: "1.4.2", children: null }, { id: "1.4.3", children: null }, { id: "1.4.4", children: null }] }],
result = getDifference(tree1, tree2);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
来源:https://stackoverflow.com/questions/62192673/javascript-quadtree-comparison