Leetcode 2628. JSON Deep Equal:JSON数据深度相等


题目如下:

此题就是比较两个JSON数据是否深度相等,这在日常开发中处理树形JSON还是比较容易遇到的。

我的思路是在areDeeplyEqual函数中定义一个标识是否相等的变量isEqual为true,然后在接下来的逻辑中检查每个值是否相等,遇到不相等的时候将isEqual置为false,而且一旦isEqual置为false时,接下来的执行也就没有比较再继续了,return停止执行后续都有逻辑执行。由于是深层JSON,需要递归执行,所以areDeeplyEqual函数中定义一个compare比较函数。

主要的核心逻辑在compare函数里,按照o1和o2的数据类型来进行不同的比较策略,当遇到子项依然是对象或数组时,则将子项递归执行compare比较。

为了避免较为重复和繁琐的类型判断,实现judgeType函数来判定数据类型,主要为了能很好地区分null、对象、数组和简单类型。

代码如下:

const entries = obj => Object.entries(obj);

// 重写一个判断数据类型的函数
const judgeType = val => {
    if (val === null) return 'NULL';
    if (Array.isArray(val)) return 'ARRAY';
    if (val !== null && typeof val === 'object') return 'OBJECT';
    return typeof val;
}

var areDeeplyEqual = function (o1, o2) {
    // 一开始设定是否等于标识为true
    let isEqual = true;
    // 比较函数
    const compare = (o1, o2) => {
        // 如果两个值类型不同,肯定不相等
        if (judgeType(o1) !== judgeType(o2)) {
            console.log('28');
            isEqual = false;
            return;
        } else if ((typeof o1 !== 'object' && typeof o2 !== 'object') && o1 !== o2) {
            // 如果是基本类型的话,直接比较,如果严格不等于,isEqual置为false
            isEqual = false;
            return;
        } else if (judgeType(o1) === 'OBJECT' && judgeType(o2) === 'OBJECT') {
            // 如果两个都是非数组的对象
            if (entries(o1).length !== entries(o2).length) {
                // 对象的key数不一样多,肯定不相等
                isEqual = false;
                return;
            } else {
                // 两个对象的key数一样多时,需要对比key-value值是否匹配
                entries(o1).forEach(([key, val]) => {
                    if (['OBJECT', 'ARRAY'].includes(judgeType(val))) {
                        // 如果当前属性的value依然是对象或数字,则递归执行比较
                        compare(val, o2[key]);
                    } else if (val !== o2[key]) {
                        // 如果是简单类型,则直接比较是否相等
                        isEqual = false;
                        return;
                    }
                });
            }
        } else if (judgeType(o1) === "ARRAY" && judgeType(o2) === "ARRAY") {
            // 如果两个都是数组类型
            if (o1.length !== o2.length) {
                // 长度相等,则isEqual置为false
                isEqual = false;
                return;
            }
            // 如果长度相等,则需要遍历比较数组的每个元素是否对应相等
            o1.forEach((item, index) => {
                if (['OBJECT', 'ARRAY'].includes(judgeType(item))) {
                    // 如果当前元素依然是对象或数字,则递归执行比较
                    compare(item, o2[index]);
                } else if (item !== o2[index]) {
                    // 如果是简单类型,则直接比较是否相等
                    isEqual = false;
                    return;
                }
            });
        }
    };
    // 还是执行比较函数
    compare(o1, o2);
    // 返回是否相等的标识
    return isEqual;
};

此实现执行效率不如力扣官方给出的实现高,但思维难度较小,容易想到,并且通过区分不同类型来做不同的比较策略,这个思路较为简单清晰,所以记录一下。


一片冰心在玉壶