• 递归映射树增删监控


    讲解

    原始数据

    let arr = [
        {"id": 2, "parentId": 1, "name": "Fruits"},
        {"id": 3, "parentId": 2, "name": "apple"},
        {"id": 4, "parentId": 2, "name": "orange"},
        {"id": 5, "parentId": 2, "name": "tomato"},
        {"id": 6, "parentId": 1, "name": "Vegetables"},
        {"id": 7, "parentId": 6, "name": "carrot"},
        {"id": 8, "parentId": 6, "name": "cabbage"},
        {"id": 9, "parentId": 6, "name": "potato"},
        {"id": 10, "parentId": 6, "name": "lettuce"},
        {"id": 11, "parentId": 0, "name": "Cars"},
        {"id": 13, "parentId": 8, "name": "Cars"},
        {"id": 1, "parentId": 0, "name": "Foods"},
    ];
    

    parentId 为0 是第一级别

    生成映射树const tree = convert(arr);

    [
        {
            "idIP": 11,
            "ip": {
                "id": 11,
                "parentId": 0,
                "name": "Cars"
            },
            "children": []
        },
        {
            "idIP": 1,
            "ip": {
                "id": 1,
                "parentId": 0,
                "name": "Foods"
            },
            "children": [
                {
                    "idIP": 2,
                    "ip": {
                        "id": 2,
                        "parentId": 1,
                        "name": "Fruits"
                    },
                    "children": [
                        {
                            "idIP": 3,
                            "ip": {
                                "id": 3,
                                "parentId": 2,
                                "name": "apple"
                            },
                            "children": []
                        },
                        {
                            "idIP": 4,
                            "ip": {
                                "id": 4,
                                "parentId": 2,
                                "name": "orange"
                            },
                            "children": []
                        },
                        {
                            "idIP": 5,
                            "ip": {
                                "id": 5,
                                "parentId": 2,
                                "name": "tomato"
                            },
                            "children": []
                        }
                    ]
                },
                {
                    "idIP": 6,
                    "ip": {
                        "id": 6,
                        "parentId": 1,
                        "name": "Vegetables"
                    },
                    "children": [
                        {
                            "idIP": 7,
                            "ip": {
                                "id": 7,
                                "parentId": 6,
                                "name": "carrot"
                            },
                            "children": []
                        },
                        {
                            "idIP": 8,
                            "ip": {
                                "id": 8,
                                "parentId": 6,
                                "name": "cabbage"
                            },
                            "children": [
                                {
                                    "idIP": 13,
                                    "ip": {
                                        "id": 13,
                                        "parentId": 8,
                                        "name": "Cars"
                                    },
                                    "children": []
                                }
                            ]
                        },
                        {
                            "idIP": 9,
                            "ip": {
                                "id": 9,
                                "parentId": 6,
                                "name": "potato"
                            },
                            "children": []
                        },
                        {
                            "idIP": 10,
                            "ip": {
                                "id": 10,
                                "parentId": 6,
                                "name": "lettuce"
                            },
                            "children": []
                        }
                    ]
                }
            ]
        }
    ]
    

    我们发现我们对原数据进行增删无法对原数组进行监控, 需要添加增删的监控

    const arr1 = new Proxy(arr, {...}

    完整代码如下

    let arr = [
        {"id": 2, "parentId": 1, "name": "Fruits"},
        {"id": 3, "parentId": 2, "name": "apple"},
        {"id": 4, "parentId": 2, "name": "orange"},
        {"id": 5, "parentId": 2, "name": "tomato"},
        {"id": 6, "parentId": 1, "name": "Vegetables"},
        {"id": 7, "parentId": 6, "name": "carrot"},
        {"id": 8, "parentId": 6, "name": "cabbage"},
        {"id": 9, "parentId": 6, "name": "potato"},
        {"id": 10, "parentId": 6, "name": "lettuce"},
        {"id": 11, "parentId": 0, "name": "Cars"},
        {"id": 13, "parentId": 8, "name": "Cars"},
        {"id": 1, "parentId": 0, "name": "Foods"},
    ];
    
    //转化树  parentId=0 是顶级
    function convert(arr, id = 0) {
        let res = [];
        for (let i = 0; i < arr.length; i++) {
            if (arr[i].parentId == id) {
                let obj = {};
                obj.idIP = arr[i].id;
                obj.ip = arr[i];
                res.push(obj);
                let func = convert.bind();
                obj.children = func(arr, arr[i].id);
            }
        }
        return res;
    }
    
    // splice 索引问题
    // 第一个参数
    const computeStartIndex = (startIndex, len) => {
        // 处理索引负数的情况
        if (startIndex < 0) {
            return startIndex + len > 0 ? startIndex + len : 0;
        }
        return startIndex >= len ? len : startIndex;
    }
    //第二个参数
    const computeDeleteCount = (startIndex, len, deleteCount, argumentsLen) => {
        // 删除数目没有传,默认删除startIndex及后面所有的
        if (argumentsLen === 1)
            return len - startIndex;
        // 删除数目过小
        if (deleteCount < 0)
            return 0;
        // 删除数目过大
        if (deleteCount > len - deleteCount)
            return len - startIndex;
        return deleteCount;
    }
    
    // 树
    const tree = convert(arr);
    // 监控数组的增删
    const arr1 = new Proxy(arr, {
        get(target, prop) {
            const val = target[prop];
            if (typeof val === 'function') {
                if (['push', 'unshift', 'pop', 'shift', 'splice'].includes(prop)) {
                    return function () {
                        if (['unshift', 'push'].includes(prop)) {
                            for (let key in arguments) {
                                if (arguments[key].id) {
                                    let obj1 = {idIP: arguments[key].id, ip: arguments[key], children: []};
                                    if (arguments[key].parentId === 0) {
                                        prop === 'push' ? tree.push(obj1) : tree.unshift(obj1)
                                    } else {
                                        searchId(tree, obj1, obj1.ip.parentId, prop)
                                    }
                                }
                            }
                        }
                        if (prop === 'shift') {
                            searchId(tree, {}, arr[0].idIP, 'shift')
                        }
                        if (prop === 'pop') {
                            searchId(tree, {}, arr[arr.length - 1].id, 'pop')
                        }
                        if (prop === 'splice' && arguments.length > 0) {
                            // 处理索引负数的问题
                            let arr2 = arr1.slice(computeStartIndex(arguments[0], arr.length), computeDeleteCount(arguments[0], arr.length, arguments[1], arguments.length))
                            // 删除
                            for (let i = 0; i < arr2.length; i++) {
                                searchId(tree, {}, arr2[i].id, 'splice')
                            }
                            // 增加
                            if (arguments.length > 2) {
                                for (let key = 2; key < arguments.length; key++) {
                                    if (arguments[key].id) {
                                        let obj1 = {idIP: arguments[key].id, ip: arguments[key], children: []};
                                        if (arguments[key].parentId === 0) {
                                            tree.push(obj1)
                                        } else {
                                            searchId(tree, obj1, obj1.ip.parentId, 'push')
                                        }
                                    }
                                }
                            }
                        }
                        return Array.prototype[prop].apply(target, arguments);
                    }
                }
                return val.bind(target);
            }
            return val;
        }
    });
    
    // 转化树响应转化
    const searchId = (tree, obj, parentId, str) => {
        for (let i = 0; i < tree.length; i++) {
            if (tree[i].idIP === parentId) {
                if (str === 'push') {
                    tree[i].children.push(obj)
                } else if (str === 'unshift') {
                    tree[i].children.unshift(obj)
                } else if (str === 'pop') {
                    tree.pop();
                } else if (str === 'shift') {
                    tree.shift();
                } else if (str === 'splice') {
                    tree.splice(i, 1)
                }
                return;
            } else {
                if (tree[i].children.length) {
                    searchId(tree[i].children, obj, parentId, str)
                }
            }
        }
    }
    

    决定自己的高度的是你的态度,而不是你的才能

    记得我们是终身初学者和学习者

    总有一天我也能成为大佬

  • 相关阅读:
    微软职位内部推荐-SOFTWARE ENGINEER II
    微软职位内部推荐-SOFTWARE ENGINEER II
    微软职位内部推荐-SDEII for Windows Phone Apps
    微软职位内部推荐-SDEII for Windows Phone Apps
    微软职位内部推荐-Software Engineer II-SDP
    微软职位内部推荐-SDE II
    微软职位内部推荐-Senior Software Engineer-SDP
    微软职位内部推荐-Senior Software Engineer
    微软职位内部推荐-Software Engineer II-Office Incubation
    微软职位内部推荐-Senior Software Engineer-Office Incubation
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/14831929.html
Copyright © 2020-2023  润新知