everycode
everycode copied to clipboard
2014年12月2日 D4
需求
写一个函数判断两个对象结构相同。具体需求:
设参数分别为left, right, 当以下全部满足,则返回true,否则返回false
- left, right必须是都是对象,否则返回false
- left, right中得属性必须类型相同,否则返回false.
- 属性不存在时,算作类型相同。如left.a = 1, right.a不存在,则依然算通过。(实际数据返回有些属性可以不存在)
- 对于数组类型,只取第一个元素判断即可。若数组为空,不判断数组中的元素。
- 以上满足, 返回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?"通过":"不通过"))};
第一个通过 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])})}
不通过
/*
* 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;
}
第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;
}
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
的人儿,伤不起