everycode icon indicating copy to clipboard operation
everycode copied to clipboard

2014年12月2日 D4

Open Bosn opened this issue 10 years ago • 4 comments

需求

写一个函数判断两个对象结构相同。具体需求:

设参数分别为left, right, 当以下全部满足,则返回true,否则返回false

  1. left, right必须是都是对象,否则返回false
  2. left, right中得属性必须类型相同,否则返回false.
  3. 属性不存在时,算作类型相同。如left.a = 1, right.a不存在,则依然算通过。(实际数据返回有些属性可以不存在)
  4. 对于数组类型,只取第一个元素判断即可。若数组为空,不判断数组中的元素。
  5. 以上满足, 返回true

接口

/*
 * param {object} left 
 * param {object} right
 * return {boolean}
 */
function judgeStructure(left, right){

}

示例

judgeStructure({x : 1}, {x : 100}); // true
judgeStructure({x : 1}, {x : true}); // false
judgeStructure({x : 1}, {}); // true

判断

// 执行后,调用judge()查看结果
function judge(){var func=judgeStructure;var result=function(){var cases=[{left:{x:1},right:{x:false},expect:false},{left:{x:1},right:{},expect:true},{left:null,right:{},expect:false},{left:{x:{y:1}},right:{x:{y:2}},expect:true},{left:{x:1,y:2,z:3},right:{x:1,y:3,z:{}},expect:false},{left:{x:[{x:1}]},right:{x:[{x:false}]},expect:false},{left:{x:[{x:1}]},right:{x:[{x:255}]},expect:true},{left:{x:[{x:1}]},right:{x:[{x:255},{x:false}]},expect:true},{left:{x:[{x:1}]},right:{x:[]},expect:true},{left:{x:[]},right:{x:[{x:1}]},expect:true},{left:{x:[[1,2],[3,4]]},right:{x:[[5,6],[7,8]]},expect:true},{left:{x:[[1,2],[3,4]]},right:{x:[[5,6],[false,true]]},expect:true},{left:{x:[[1,2],[3,4]]},right:{x:[["5",6],[7,8]]},expect:false},{left:{x:[{x:1}]},right:{x:[{},{x:100}]},expect:true},{left:{o1:{p1:1,p2:true,p3:"test",pObj:{x:[{x:1}],y:2,z:3}}},right:{o1:{p1:200,p2:false,p3:"xxx",pObj:{y:2,z:3,z2:"hahaha"}}},expect:true},{left:{o1:{p1:1,p2:true,p3:"test",pObj:{x:[{x:1}],y:2,z:3}}},right:{o1:{p1:200,p2:false,p3:"xxx",pObj:{y:2,z:false,z2:"hahaha"}}},expect:false},{left:{o1:{p1:1,p2:true,p3:"test",pObj:{x:[{x:1}],y:2,z:3}}},right:{o1:{p1:200,p2:false,p3:"xxx",pObj:{y:2,z:3,z2:"hahaha",x:[{x:"1"}]}}},expect:false}];for(var i=0;i<cases.length;i++){if(func(cases[i].left,cases[i].right)!==cases[i].expect){console.error("不通过!case"+(i+1)+":\n"+JSON.stringify(cases[i],null,4)+"\n不正确!期望结果应是"+cases[i].expect+", 实际执行却是"+!cases[i].expect);return false}}return true}();console.log("判定结果:"+(result?"通过":"不通过"))};

Bosn avatar Dec 02 '14 01:12 Bosn

第一个通过 by @酱油

function judgeStructure(left, right) {
    return (left && right === undefined) ?
        true :
        ((left === null || right === null) ?
            false :
            (typeof left !== typeof right ?
                false :
                (typeof left !== "object" ?
                    true :
                    (left instanceof Array ^ right instanceof Array) ?
                        false :
                        (left instanceof Array ? 
                            (left.length && right.length ?
                                judgeStructure(left[0], right[0]) :
                                true) :
                            Object.keys(left).every(function(key) {
                                return judgeStructure(left[key], right[key]);
                            })))));
}

Case 14 结果应为 true

(if else 多了没意思啊,纯业务了 -。 -

压缩结果:

function judgeStructure(a,b){return a&&void 0===b?!0:null===a||null===b?!1:typeof a!=typeof b?!1:"object"!=typeof a?!0:a instanceof Array^b instanceof Array?!1:a instanceof Array?a.length&&b.length?judgeStructure(a[0],b[0]):!0:Object.keys(a).every(function(c){return judgeStructure(a[c],b[c])})}

XadillaX avatar Dec 02 '14 02:12 XadillaX

不通过

           
/*
 * param {object} left 
 * param {object} right
 * return {boolean}
 */
function judgeStructure(left, right){
    for(var a in left){
        if(right[a] && right[a]!=left[a]){
            return false;
        }
    }
    return false;
}

fireflyhoo avatar Dec 02 '14 03:12 fireflyhoo

第2个通过 by @酱油

/*
 * param {object} left 
 * param {object} right
 * return {boolean}
 */
function judgeStructure(left, right){
    if(!left || !right)
        return false;
    if(typeof left !== "object" || typeof right !== "object")
        return false;

    var toStr = Object.prototype.toString;

    for(var p in left) {
        if(right[p] !== undefined) {
            if(toStr.apply(right[p]) !== toStr.apply(left[p]))
                return false;
            else {
                if(toStr.apply(right[p]) === '[object Array]') {
                    if(left[p].length > 0 && right[p].length > 0)
                        return judgeStructure(left[p][0], right[p][0]);
                }else if(typeof left[p] === 'object'){
                    return judgeStructure(left[p], right[p]);
                }                   

            }

        }
    }
    return true;
}

businiaowa avatar Dec 02 '14 03:12 businiaowa

function judgeStructure(left, right) {
    function getType(obj) {
        return ({}).toString.call(obj);
    }

    function compare(obj1, obj2) {
        var type1 = getType(obj1);
        var type2 = getType(obj2);
        if (type1 != type2) {
            return false
        } else if (type1 === "[object Array]") {
            if (obj1.length > 0 && obj2.length > 0) {
                if (!compare(obj1[0], obj2[0])) {
                    return false
                };
            }
        } else if (type1 === "[object Object]") {
            for (var p in obj1) {
                if (obj2[p] == undefined) {
                    continue
                } else {
                    if (!compare(obj1[p], obj2[p])) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
    if (typeof left != "object" || typeof right != "object" || left == null || right == null) {
        return false
    }
    return compare(left, right)
}

continue写成break的人儿,伤不起

nunnly avatar Dec 02 '14 12:12 nunnly