任务

请在 index.html 文件中,编写 arraysSimilar 函数,实现判断传入的两个数组是否相似。具体需求:

  1. 数组中的成员类型相同,顺序可以不同。例如 [1, true] 与 [false, 2] 是相似的。
  2. 数组的长度一致。
  3. 类型的判断范围,需要区分: String , Boolean, Number, undefined, null, 函数, 日期, window.

    当以上全部满足,则返回"判定结果:通过",否则返回"判定结果:不通过"。

这是一个奇怪的需求,主要是要求“相似”的判断。

  • 第一直觉是直接对数组排序,然后比较类型。但由于 JS 比较大小的特性,这是不对的。
  • 那么需要变换一下,我这里是取每个元素的类型名简写,这样可以近似 \(O(NlogN)\) 排字典序,再将其作为整个数组的 typo ,就可以近似 \(O(N)\) 比较数组是否相似。
  • 第二个要注意的点是对无效参数的判断,一开始是用 == null 来判断 nullundefined 的,但是要求参数类型为数组,所以用 instanceof 判断。
  • 获取类型的替代方案是用 Object.prototype.toString() ,可以准确地拿到原型链上对象的类名,但是函数可能会被重写,所以不优先使用。
  • 但其实使用 instanceof 是有问题的,考虑不同页面的构造函数可以不同——因此判断数组可以用 Array.isArray() 代替,参考
        /*
* param1 Array
* param2 Array
* return true or false
*/
function arraysSimilar(arr1, arr2) {
// 获取单个元素的类型名简写,已经满足需求
// 替代方案:考虑用 Object.prototype.toString ,但会被 hack
function getTypeNameS(item) {
if (item === null)
return 'nl';
else if (item instanceof Date)
return 'd';
else if (item instanceof Window)
return 'w';
else
return (typeof item)[0];
}
// 获取整个数组排序后的 typo
function getArrayTypo(arr) {
return arr.map(function (item) {
return getTypeNameS(item);
}).sort().join('');
}
// 可以判断 == null ,但由于要求类型为数组,那就用 instanceof
if (!(arr1 instanceof Array) || !(arr2 instanceof Array))
return false;
// 长度不等的情况,也可以合并到 typo 比较中
if (arr1.length != arr2.length)
return false;
// 对于 typo 使用内置的字符串比较
return getArrayTypo(arr1) == getArrayTypo(arr2);
}

下面是另一种实现:

        function arraysSimilar(arr1, arr2) {
// 用 Object.prototype.toString ,但会被 hack
function getTypeName(item) {
return item === null ? 'Null' : Object.prototype.toString.call(item).slice(8, -1);
} // 获取整个数组排序后的 typo
function getArrayTypo(arr) {
return arr.map(function (item) {
return getTypeName(item);
}).sort().join('');
} // 使用 ECMAScript 5.1 的 isArray() 函数
if (!Array.isArray(arr1) || !Array.isArray(arr2))
return false;
// 长度不等的情况
if (arr1.length != arr2.length)
return false;
// 对于 typo 使用内置的字符串比较
return getArrayTypo(arr1) == getArrayTypo(arr2);
}

本文基于知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议发布,欢迎引用、转载或演绎,但是必须保留本文的署名BlackStorm以及本文链接http://www.cnblogs.com/BlackStorm/p/7182227.html,且未经许可不能用于商业目的。如有疑问或授权协商请与我联系

imooc《JavaScript深入浅出》上的一个 arraysSimilar 函数的更多相关文章

  1. JavaScript深入浅出第2课:函数是一等公民是什么意思呢?

    摘要: 听起来很炫酷的一等公民是啥? <JavaScript深入浅出>系列: JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼? JavaScript深入浅出第2课:函 ...

  2. javascript随机数发现的一个parseInt函数的问题

    前几天想伪造一些数据,用到了随机数,没有自己写,便在网上找了一下,找到了这篇文章:https://www.cnblogs.com/starof/p/4988516.html .之后测试了一下,发现了一 ...

  3. 《你不知道的JavaScript(上)》笔记——函数作用域和块作用域

    关于函数声明:如果 function 是声明中的第一个词, 那么就是一个函数声明, 否则就是一个函数表达式.例如匿名函数这种形式,函数会被当作函数表达式而不是一个标准的函数声明来处理. (functi ...

  4. JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?

    <JavaScript 深入浅出>系列: JavaScript 深入浅出第 1 课:箭头函数中的 this 究竟是什么鬼? JavaScript 深入浅出第 2 课:函数是一等公民是什么意 ...

  5. JavaScript深入浅出第5课:Chrome是如何成功的?

    摘要: Chrome改变世界. <JavaScript深入浅出>系列: JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼? JavaScript深入浅出第2课:函数是一 ...

  6. JavaScript深入浅出第4课:V8引擎是如何工作的?

    摘要: 性能彪悍的V8引擎. <JavaScript深入浅出>系列: JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼? JavaScript深入浅出第2课:函数是一等 ...

  7. JavaScript深入浅出第3课:什么是垃圾回收算法?

    摘要: JS是如何回收内存的? <JavaScript深入浅出>系列: JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼? JavaScript深入浅出第2课:函数是一 ...

  8. 函数原型属性-JavaScript深入浅出(三)

    前两次总结了JavaScript中的基本数据类型(值类型<引用类型>,引用类型<复杂值>)以及他们在内存中的存储,对内存空间有了一个简单的了解,以及第二次总结了this深入浅出 ...

  9. JavaScript移除绑定在元素上的匿名事件处理函数

    前言: 面试的时候有点蒙,结束之后想想自己好像根本就误解了面试官的问题,因为我理解的这个问题本身就没有意义.但是当时已经有一些思路,但是在一个点上被卡住. 结束之后脑子瞬间灵光,想出了当时没有迈出的那 ...

随机推荐

  1. 学习Python语言 基础语法:变量的基本使用

    Python变量 程序是用来处理数据的,变量就是用来保存数据的,通过给数据定义一个名称来保证方便记忆和识别.使用这个数据.变量可以保存所有类型的数据. Python变量的定义 在Python中,变量的 ...

  2. PHP错误处理函数register_shutdown_function

    当程序在线上运行时,如果遇到BUG,想不在前端输出错误信息,同时能及时邮件通知开发者,register_shutdown_function函数就可以派上用场了. 注册一个会在脚本执行完成或者 exit ...

  3. Mobility Model and Routing Model about the ONE

    ONE主要的功能是节点的移动,节点间的相遇情况,路由情况以及消息的处理机制.下面简要介绍下目前ONE自带的六种移动模型和六种路由模型. Mobility Model: 从大的方面,可以分为三种,1)随 ...

  4. JAVA中byte为负数处理

    java中一定有人遇见过byte取值为负数情况,比如0xc0对应的值-64,其实应该是192,这里就需要我们转化处理 /** * Description: 负数byte转正int <BR> ...

  5. getResourceAsStream的3种路径配置

    getResourceAsStream有以下几种: 1. Class.getResourceAsStream(String path) : path 不以’/'开头时默认是从此类所在的包下取资源,以’ ...

  6. tomcat-四种运行模式和三种部署模式(优化)

    四中运行模式如下: 1-bio: 传统的Java I/O操作,同步且阻塞IO. 2-nio: JDK1.4开始支持,同步阻塞或同步非阻塞IO 3-aio(nio.2): JDK7开始支持,异步非阻塞I ...

  7. RocketMQ 分布式事务

    在RocketMQ中生产者有三种角色NormalProducer(普通).OrderProducer(顺序).TransactionProducer(事务),根据名字大概可以看出各个代表着什么作用,我 ...

  8. k8s全栈监控之metrics-server和prometheus

    一.概述 使用metric-server收集数据给k8s集群内使用,如kubectl,hpa,scheduler等 使用prometheus-operator部署prometheus,存储监控数据 使 ...

  9. springboot aop 自定义注解方式实现完善日志记录(完整源码)

    版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 一:功能简介 本文主要记录如何使用aop切面的方式来实现日志记录功能. 主要记录的信息有: 操作人,方法名,参数,运行时间,操作类型 ...

  10. 动态规划法(五)钢条切割问题(rod cutting problem)

      继续讲故事~~   我们的主人公现在已经告别了生于斯,长于斯的故乡,来到了全国最大的城市S市.这座S市,位于国家的东南部,是全国的经济中心,工商业极为发达,是这个国家的人民所向往的城市.这个到处都 ...