双树遍历

/**
 *
 * @param newTree Arr
 * @param oldTree Arr
 * @param cb Fun (newItem, oldItem, parents) => {}  newItem: newTree 的 item.  oldItem oldTree 的 item,可能会不存在. parents newItem 的 父级, 可能会不存在
 * @param conf { idKey: string, childrenKey: string }
 */
function contrastTree(newTree, oldTree, cb, conf = {idKey:'id', childrenKey: 'children'}) {
    if (!newTree || !newTree) {
        console.warn('contrastTree: newTree 和 oldTree 必须存在')
        return
    }

    if (!Array.isArray(newTree) || !Array.isArray(oldTree)) {
        console.warn('contrastTree: newTree 和 oldTree 必须为数组')
        return
    }

    if (Object.prototype.toString.apply(conf) !== '[object Object]') {
        console.warn('conf 必须为 Object')
        return
    }

    // 遍历树
    function deepEach(tree, callback, parents) {
        tree.forEach(item => {
            const Children = item[conf.childrenKey]
            const HaveChildren = Children && Array.isArray(Children)

            // 传入父级
            callback(item, parents)
            if (HaveChildren) {
                deepEach(Children, callback, item)
            }
        })
    }

    // 拉平 OldTreeArr,将arr 转为 obj格式,方便取值
    const OldTreeObj = {}

    deepEach(oldTree, (item) => {
        OldTreeObj[item[conf.idKey]] = item
    })


    // 开始双树对比
    deepEach(newTree, (newItem, parents) => {
        const OldItem = OldTreeObj[newItem[conf.idKey]]
        cb(newItem, OldItem, parents)
    })
}

 

上一篇:初识ABP vNext(7):vue身份认证管理&租户管理


下一篇:Node.js连接postgres