题目 解答 思路 具体实现代码 总结 题目 题目来自 慕课网 JavaScript 深入浅出 1-6 编程练习 请在 index.html 文件中,编写 arraysSimilar 函数,实现判断传入的两个数组是否相似。具体需求: 数组中的成员类型相同,顺序可以不同。例如 [1, true] 与 [false, 2] 是相似的。 数组的长度一致。 类型的判断范围,需要区分: String, Boolean, Number, undefined, null, 函数, 日期, window. 当以上全部满足,则返回“判定结果:通过”,否则返回“判定结果:不通过”。 题目给出了 index.html 如下: <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb18030"> <title>Untitled Document</title> </head> <body> <script type="text/javascript"> /* * param1 Array * param2 Array * return true or false */ function arraysSimilar(arr1, arr2){ } </script> <script src="testData.js"></script> </body> </html> 其中 testData.js 是测试用例,代码如下 var result = function() { //以下为多组测试数据 var cases = [{ arr1: [1, true, null], arr2: [null, false, 100], expect: true }, { arr1: [ function() {}, 100 ], arr2: [100, {}], expect: false }, { arr1: [null, 999], arr2: [{}, 444 ], expect: false }, { arr1: [window, 1, true, new Date(), "hahaha", (function() {}), undefined], arr2: [undefined, (function() {}), "okokok", new Date(), false, 2, window], expect: true }, { arr1: [new Date()], arr2: [{}], expect: false }, { arr1: [window], arr2: [{}], expect: false }, { arr1: [undefined, 1], arr2: [null, 2], expect: false }, { arr1: [new Object, new Object, new Object], arr2: [{}, {}, null ], expect: false }, { arr1: null, arr2: null, expect: false }, { arr1: [], arr2: undefined, expect: false }, { arr1: "abc", arr2: "cba", expect: false }]; //使用for循环, 通过arraysSimilar函数验证以上数据是否相似,如相似显示“通过”,否则"不通过",所以大家要完成arraysSimilar函数,具体要求,详见任务要求。 for (var i = 0; i < cases.length; i++) { if (arraysSimilar(cases[i].arr1, cases[i].arr2) !== cases[i].expect) { document.write("不通过!case" + (i + 1) + "不正确!arr1=" + JSON.stringify(cases[i].arr1) + ", arr2=" + JSON.stringify(cases[i].arr2) + " 的判断结果不是" + cases[i].expect); return false; } } return true; }(); document.write("判定结果:" + (result ? "通过" : "不通过")); 解答 各位读者在看解答前也可以自己考虑一下,看看咱们的想法是否一致,期待您在本文的留言。 思路 通过观察测试用例,可以发现,最后三个用例有不是数组的。所以我们可以先判断传入的参数是否是数组。 又因为题目中要求数组长度必须一致,这也是第二个限制条件。 最后再区分具体的类型。 理清思路我们可以分为以下步骤: 判断传入的参数是否为数组 (使用 instanceof 方法) 检查两个数组长度是否一致 分别判断数组内元素的基本数据类型 (使用 typeof 方法) 因为 typeof 只能检查基本数据类型,对于 null, Date, window 返回的都是 object,所以使用 Object.prototype.toString.apply() 来检查这些对象类型,其返回值为:'[object Null]', '[object Date]', '[object global]' 分别比较每个数组内元素的各种类型的个数,如果都相等,那么这两个数组是相似的。 具体实现代码 JavaScript代码如下 /** * ===================================================== * 请在index.html文件中,编写arraysSimilar函数,实现判断传入的两个数组是否相似。具体需求: * 1. 数组中的成员类型相同,顺序可以不同。例如[1, true] 与 [false, 2]是相似的。 * 2. 数组的长度一致。 * 3. 类型的判断范围,需要区分:String, Boolean, Number, undefined, null, 函数,日期, window. * * 当以上全部满足,则返回"判定结果:通过",否则返回"判定结果:不通过"。 * ===================================================== */ /* * param1 Array * param2 Array * return true or false */ function arraysSimilar(arr1, arr2){ if (arr1 instanceof Array && arr2 instanceof Array ) { //先判断传入的是否是数组 if (arr1.length == arr2.length) { //判断数组长度 console.log("same-length"); console.log(arr1); console.log(arr2); //开始判断数组内部是否相似 return sameLengthArraysSimilar(arr1, arr2); } else{ //两个数组长度不同返回false return false; } } else { //传入的参数不是数组返回false return false; } } /** * 判断两个等长的数组内部是否相似 * 遍历数组 * arr1中元素各种类型出现的个数是否和arr2中元素各种类型出现的个数相同 * @param {Array} arr1 数组1 * @param {Array} arr2 数组2 * @return {true,false} */ function sameLengthArraysSimilar(arr1,arr2) { var numInArr1 = 0; var numInArr2 = 0; var booleanInArr1 = 0; var booleanInArr2 = 0; var funInArr1 = 0; var funInArr2 = 0; var undefinedInArr1 = 0; var undefinedInArr2 = 0; var stringInArr1 = 0; var stringInArr2 = 0; var nullInArr1 = 0; var nullInArr2 = 0; var dateInArr1 = 0; var dateInArr2 = 0; var windowInArr1 = 0; var windowInArr2 = 0; for (var i = 0; i < arr1.length; i++) { if(typeof arr1[i] === 'number' ){ numInArr1 ++; } else if(typeof arr1[i] === 'boolean'){ booleanInArr1 ++; } else if(typeof arr1[i] === 'function'){ funInArr1 ++; } else if(typeof arr1[i] === 'undefined'){ undefinedInArr1 ++; } else if(typeof arr1[i] === 'string'){ stringInArr1 ++; } else if(typeof arr1[i] ==='object'){ if(Object.prototype.toString.apply(arr1[i]) === '[object Null]'){ nullInArr1 ++; } else if(Object.prototype.toString.apply(arr1[i]) === '[object Date]'){ dateInArr1 ++; } else if(Object.prototype.toString.apply(arr1[i]) === '[object global]'){ windowInArr1 ++; } } if(typeof arr2[i] === 'number'){ numInArr2 ++; } else if(typeof arr2[i] === 'boolean'){ booleanInArr2 ++; } else if(typeof arr2[i] === 'function'){ funInArr2 ++; } else if(typeof arr2[i] === 'undefined'){ undefinedInArr2 ++; } else if(typeof arr2[i] === 'string'){ stringInArr2 ++; } else if(typeof arr2[i] ==='object'){ if(Object.prototype.toString.apply(arr2[i]) === '[object Null]'){ nullInArr2 ++; } else if(Object.prototype.toString.apply(arr2[i]) === '[object Date]'){ dateInArr2 ++; } else if(Object.prototype.toString.apply(arr2[i]) === '[object global]'){ windowInArr2 ++; } } } console.log("num---"+numInArr1); console.log("num---"+numInArr2); console.log("boo---"+booleanInArr1); console.log("boo---"+booleanInArr2); console.log("null---"+nullInArr1); console.log("null---"+nullInArr2); console.log("window---"+windowInArr1); console.log("window---"+windowInArr2); console.log("date---"+dateInArr1); console.log("date---"+dateInArr2); console.log("string---"+stringInArr1); console.log("string---"+stringInArr2); console.log("fun---"+funInArr1); console.log("fun---"+funInArr2); console.log("undefined---"+undefinedInArr1); console.log("undefined---"+undefinedInArr2); if(numInArr1 == numInArr2 && booleanInArr1==booleanInArr2 && funInArr1==funInArr2 && undefinedInArr1==undefinedInArr2 && stringInArr1==stringInArr2 && nullInArr1==nullInArr2 && dateInArr1==dateInArr2 && windowInArr1==windowInArr2){ console.log('================================true'); return true; }else{ console.log('================================false'); return false; } } 总结 上述代码完美的跑完所有的测试用例,读者 点击这里查看结果,并且可以按 f12 看 Console 信息, 里面有代码的执行过程。 当然你也可以复制本文的 JavaScript 代码,在 慕课网的习题 下跑一下,也可以看到 判定结果:通过 的结果 完整源代码在我的 GitHub javascript-test/arraysSimilar/ 仓库中 其实我的代码逻辑并不复杂,有点空间换时间的感觉,执行效率应该是较高的。没有用 JavaScript 封装的任何函数,完全是自己写的。其实代码除去 console.log() 也并没有多少行。 各位读者有什么好的想法欢迎留言交流!