js 判断两个数组是不是子集关系

29 篇文章 0 订阅

     目前还有些限制,比如连续嵌套数组的情况,有办法解决的欢迎指点一下  

 

 const obj1 = [{ a: 1 }, { a: 1, b: 2 }, { a: 2 }];
        const obj2 = [{ a: 1 }, { a: 2 }, { a: 1, b: 2, c: 3 }];
        var result = this.checkArrayInArray(obj1, obj2);
        console.log(result);
 checkArrayInArray(a, b) {
        if (a.length > b.length) {
            return false;
        }
        return this.checkArrInArr(a, b);
    },
    checkArrInArr(a, b) {
        var bool;
        for (var i = 0; i < a.length; ++i) {
            if (a[i] instanceof Array) {
                bool = this.checkArrInArr(a[i], b);
                if (!bool) return false;
            }
            else if (a[i] instanceof Object) {
                bool = this.checkObjInArr(a[i], b);
                if (!bool) return false;
            }
            else {
                bool = this.checkBasicInArr(a[i], b);
                if (!bool) return false;
            }
        }
        return true;
    },
    checkObjInArr(a, b) {
        for (var i = 0; i < b.length; ++i) {
            var bool =  this.checkObjInObj(a, b[i]);
            if (bool) return true;
        }
        return false;
    },
    checkObjInObj(a, b) {
        var n = 0;
        for (var i in a) {
            if (a[i] instanceof Array) {
                if (b instanceof Array) {
                    return this.checkArrInArr(a[i], b);
                }else{
                    return false;
                }

            } else if (a[i] instanceof Object) {
                if(b instanceof Object){
                    return this.checkObjInObj(a[i], b);
                }else{
                    return false;
                }
            } else {
                if (b.hasOwnProperty(i) && a[i] == b[i]) {
                    n++;
                }
            }
        }
        if (n == Object.keys(a).length) {
            return true;
        }
        return false;
    },
    checkBasicInArr(a, b) {
        return b.includes(a);
    },

 

同事的2.0版本

 

 

const dataType = (data) => {

    const type = Object.prototype.toString.call(data);

    const startIndex = type.indexOf(' ') + 1;

    return type.slice(startIndex, -1);

};

const jsonContrast = (obj1, obj2) => {

    let flag = true;

    function compare(obj1, obj2) {

        // 数组情况

        const oldType = dataType(obj1);

        const newType = dataType(obj2);

        if (oldType !== newType) {

            flag = false;

        } else if (oldType === 'Object') { // 对象类型判断属性是否存在

            flag = objectCompare(obj1, obj2);

        } else if (oldType === 'Array') {

            flag = arrayCompare(obj1, obj2);

        }

        if (flag === false) {

            return false;

        } else {

            return true;

        }

    }

    return compare(obj1, obj2);

};

// 对象对比

function objectCompare(obj1, obj2) {

    let flag = true;

    for (let [k, v] of Object.entries(obj1)) { // 方法返回一个给定对象自身可枚举属性的键值对数组

        if (!flag) break; // 如果flag变为false说明数据存在差异应跳出循环

        if (obj2.hasOwnProperty(k)) { // 属性存在,判断类型

            if (dataType(v) === dataType(obj2[k]) && (dataType(v) === 'Object' || dataType(v) === 'Array')) { // 对象类型

                flag = jsonContrast(v, obj2[k]);

            } else if (dataType(v) !== dataType(obj2[k])) { // 其他类型

                flag = false;

            }

        } else {

            flag = false;

        }

    }

    if (flag === false) {

        return false;

    } else {

        return true;

    }

}

// 数组对比

function arrayCompare(obj1, obj2) {

    let flag = true;

    let arrFlag = true;

    let objFlag = true;

    const obj1_statistics = {

        String: 0,

        Number: 0,

        Boolean: 0,

        Array: 0,

        Object: 0

    };

    const obj2_statistics = {

        String: 0,

        Number: 0,

        Boolean: 0,

        Array: 0,

        Object: 0

    };

    const tag = ['String', 'Number', 'Boolean', 'Array', 'Object'];

    const obj1_data_arr = [];

    const obj2_data_arr = [];

    const obj1_data_obj = [];

    const obj2_data_obj = [];

 

    // 数组对比首先对比长度

    if (obj1.length > obj2.length) {

        flag = false;

    } else {

        // 因为数组中存在多个相同类型,且顺序可以是不固定的,需要对拉个数据的统一数据类型分别进行统计

        // 且如果是复杂类型的数据还需做,另外存储做对比,也许新数据的复杂类型会比老数据多,也有可能存在两个对象的内容相同的情况,以及数据的所在的前后顺序不一致等情况需要做单独处理

        for (let i in obj1) {

            const type = dataType(obj1[i]);

            ++obj1_statistics[type];

            if (type === 'Array') {

                obj1_data_arr.push(obj1[i]);

            }

            if (type === 'Object') {

                obj1_data_obj.push(obj1[i]);

            }

        }

        for (let i in obj2) {

            const type = dataType(obj2[i]);

            ++obj2_statistics[type];

            if (type === 'Array') {

                obj2_data_arr.push(obj2[i]);

            }

            if (type === 'Object') {

                obj2_data_obj.push(obj2[i]);

            }

        }

        // 数据处理完成之后,首先比较数据统计数量,如果新数据两小于老数据量说明数据有差异

        const statistics_result = tag.findIndex(t => obj1_statistics[t] > obj2_statistics[t]);

        if (statistics_result === -1) {

            arrFlag = children(obj1_data_arr, obj2_data_arr);

            objFlag = children(obj1_data_obj, obj2_data_obj);

        } else {

            flag = false;

        }

    }

 

    if (!arrFlag || !objFlag) {

        flag = false;

    }

    if (flag === false) {

        return false;

    } else {

        return true;

    }

}

 

function children(obj1_data, obj2_data) {

    let flag = true;

    let chelidFlag = true;

    outside: for (let i = 0; i < obj1_data.length; i++) { // 为for循环添加label便于在内部终止循环

        for (let j = 0; j < obj2_data.length; j++) {

            if (dataType(obj1_data[i]) === dataType(obj2_data[j]) && (dataType(obj1_data[i]) === 'Array' || dataType(obj1_data[i]) === 'Object')) {

                flag = jsonContrast(obj1_data[i], obj2_data[j]);

                if (flag === true) {

                    if (obj1_data.length !== i) {

                        obj1_data.splice(i, 1);

                        obj2_data.splice(j, 1);

                        chelidFlag = children(obj1_data, obj2_data);

                        if (chelidFlag === false) {

                            break outside;

                        }

                    }

                    break outside;

                }

            }

        }

    }

 

    if (flag === false || chelidFlag === false) {

        return false;

    } else {

        return true;

    }

}

//设定json--准备调用

var jsonA = {

    "a": { b: 2 },

    "d": [1, [[], { a: 1, b: [{ d: [{ e: [{}, []] }] }] }, { a: 1, b: 2 }, { a: [{ b: 1 }] }, 1]]

};

var jsonB = {

    "a": { b: 2 },

    "d": [1, [{ a: [{ b: 1 }] }, [], { a: 1, b: [{ d: [{ e: [[], {}] }] }] }, { d: 1 }, { a: 1, b: 1 }, 1]]

};

console.log(jsonContrast(jsonA, jsonB), '???');

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值