2700.两个对象之间的差异
链接:2700.两个对象之间的差异
难度:Medium
标签:
简介:请你编写一个函数,它接收两个深度嵌套的对象或数组 obj1 和 obj2 ,并返回一个新对象表示它们之间差异。
题解 1 - typescript
- 编辑时间:2023-05-25
- 执行用时:76ms
- 内存消耗:45.3MB
- 编程语言:typescript
- 解法介绍:dfs。
// 特殊标识符,在左右相等时返回
const same = Symbol('same');
// 存储所有已经存在的key
function mergeKey(key1: string[], key2: string[]) {
    const set1 = new Set(key1);
    const set2 = new Set(key2);
    const res = new Set<string>();
    for (const k of set1) {
        if (set2.has(k)) res.add(k);
    }
    return res;
}
function objDiff(obj1: any, obj2: any, topLevel = true): any {
    const t1 = typeof obj1;
    const t2 = typeof obj2;
    // 类型不等,肯定不等
    if (t1 !== t2) return [obj1, obj2];
    // 如果不是对象,直接判断是否相等
    if (t1 !== 'object') return obj1 === obj2 ? same : [obj1, obj2];
    // 如果是null或undefined,直接判断防止下面出错
    if (obj1 === null || obj1 === undefined || obj2 === null || obj2 === undefined) return same;
    // 如果一个是数组一个不是数组,那就不等
    if (
        (!Array.isArray(obj1) && Array.isArray(obj2)) ||
        (Array.isArray(obj1) && !Array.isArray(obj2))
    )
        return [obj1, obj2];
    // 此时肯定是对象或数组
    // 拿所有共存的key
    const keys = mergeKey(Object.keys(obj1), Object.keys(obj2));
    const res = {};
    // 遍历obj1中所有的kv
    for (const [k, v] of Object.entries(obj1).filter(([k]) => keys.has(k))) {
        // 递归比较,利用topLevel记录是不是顶层
        const diff = objDiff(v, obj2[k], false);
        // 如果不同就存储
        if (diff != same) res[k] = diff;
    }
    // 如果是空的,但是是顶层的,那就返回相等
    if (Object.keys(res).length === 0 && !topLevel) return same;
    // 否则顶层要返回控对象
    return res;
}