JavaScript: Quadtree comparison

怎甘沉沦 提交于 2021-01-28 05:41:01

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!