首页 文章 精选 留言 我的

精选列表

搜索[javascript库],共10000篇文章
优秀的个人博客,低调大师

JavaScript数组去重(12种方法,史上最全)

数组去重,一般都是在面试的时候才会碰到,一般是要求手写数组去重方法的代码。如果是被提问到,数组去重的方法有哪些?你能答出其中的10种,面试官很有可能对你刮目相看。 在真实的项目中碰到的数组去重,一般都是后台去处理,很少让前端处理数组去重。虽然日常项目用到的概率比较低,但还是需要了解一下,以防面试的时候可能回被问到。 注:写的匆忙,加上这几天有点忙,还没有非常认真核对过,不过思路是没有问题,可能一些小细节出错而已。 数组去重的方法 一、利用ES6 Set去重(ES6中最常用) functionunique(arr){ returnArray.from(newSet(arr)) }vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}];console.log(unique(arr)) //[1,"true",true,15,false,undefined,null,NaN,"NaN",0,"a",{},{}] 不考虑兼容性,这种去重的方法代码最少。这种方法还无法去掉“{}”空对象,后面的高阶方法会添加去掉重复“{}”的方法。 二、利用for嵌套for,然后splice去重(ES5中最常用) functionunique(arr){ for(vari=0;i<arr.length;i++){ for(varj=i+1;j<arr.length;j++){ if(arr[i]==arr[j]){//第一个等同于第二个,splice方法删除第二个 arr.splice(j,1); j--; } } }returnarr; }vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}]; console.log(unique(arr)) //[1,"true",15,false,undefined,NaN,NaN,"NaN","a",{…},{…}]//NaN和{}没有去重,两个null直接消失了 双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个值。 想快速学习更多常用的ES6语法,可以看我之前的文章《学习ES6笔记──工作中常用到的ES6语法》。 三、利用indexOf去重 functionunique(arr){ if(!Array.isArray(arr)){ console.log('typeerror!') return } vararray=[]; for(vari=0;i<arr.length;i++){ if(array.indexOf(arr[i])===-1){ array.push(arr[i]) } } returnarray; }vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}];console.log(unique(arr)) //[1,"true",true,15,false,undefined,null,NaN,NaN,"NaN",0,"a",{…},{…}]//NaN、{}没有去重 新建一个空的结果数组,for循环原数组,判断结果数组是否存在当前元素,如果有相同的值则跳过,不相同则push进数组。 四、利用sort() functionunique(arr){ if(!Array.isArray(arr)){ console.log('typeerror!') return; } arr=arr.sort() vararrry=[arr[0]]; for(vari=1;i<arr.length;i++){ if(arr[i]!==arr[i-1]){ arrry.push(arr[i]); } } returnarrry; } vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}]; console.log(unique(arr))//[0,1,15,"NaN",NaN,NaN,{…},{…},"a",false,null,true,"true",undefined]//NaN、{}没有去重 利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对。 五、利用对象的属性不能相同的特点进行去重(这种数组去重的方法有问题,不建议用,有待改进) functionunique(arr){ if(!Array.isArray(arr)){ console.log('typeerror!') return } vararrry=[]; varobj={}; for(vari=0;i<arr.length;i++){ if(!obj[arr[i]]){ arrry.push(arr[i]) obj[arr[i]]=1 }else{ obj[arr[i]]++ } } returnarrry; } vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}]; console.log(unique(arr))//[1,"true",15,false,undefined,null,NaN,0,"a",{…}]//两个true直接去掉了,NaN和{}去重 六、利用includes functionunique(arr){ if(!Array.isArray(arr)){ console.log('typeerror!') return } vararray=[]; for(vari=0;i<arr.length;i++){ if(!array.includes(arr[i])){//includes检测数组是否有某个值 array.push(arr[i]); } } returnarray }vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}]; console.log(unique(arr)) //[1,"true",true,15,false,undefined,null,NaN,"NaN",0,"a",{…},{…}]//{}没有去重 七、利用hasOwnProperty functionunique(arr){ varobj={}; returnarr.filter(function(item,index,arr){ returnobj.hasOwnProperty(typeofitem+item)?false:(obj[typeofitem+item]=true) }) } vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}]; console.log(unique(arr))//[1,"true",true,15,false,undefined,null,NaN,"NaN",0,"a",{…}]//所有的都去重了 利用hasOwnProperty判断是否存在对象属性 八、利用filter functionunique(arr){ returnarr.filter(function(item,index,arr){ //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素 returnarr.indexOf(item,0)===index; }); } vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}]; console.log(unique(arr))//[1,"true",true,15,false,undefined,null,"NaN",0,"a",{…},{…}] 九、利用递归去重 functionunique(arr){ vararray=arr; varlen=array.length; array.sort(function(a,b){//排序后更加方便去重 returna-b; }) functionloop(index){ if(index>=1){ if(array[index]===array[index-1]){ array.splice(index,1); } loop(index-1);//递归loop,然后数组去重 } } loop(len-1); returnarray; } vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}]; console.log(unique(arr))//[1,"a","true",true,15,false,1,{…},null,NaN,NaN,"NaN",0,"a",{…},undefined] 十、利用Map数据结构去重 functionarrayNonRepeatfy(arr){ letmap=newMap(); letarray=newArray();//数组用于返回结果 for(leti=0;i<arr.length;i++){ if(map.has(arr[i])){//如果有该key值 map.set(arr[i],true); }else{ map.set(arr[i],false);//如果没有该key值 array.push(arr[i]); } } returnarray; } vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}]; console.log(unique(arr))//[1,"a","true",true,15,false,1,{…},null,NaN,NaN,"NaN",0,"a",{…},undefined] 创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果。 十一、利用reduce+includes functionunique(arr){ returnarr.reduce((prev,cur)=>prev.includes(cur)?prev:[...prev,cur],[]); } vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}];console.log(unique(arr));//[1,"true",true,15,false,undefined,null,NaN,"NaN",0,"a",{…},{…}] 十二、[…new Set(arr)] [...newSet(arr)]//代码就是这么少----(其实,严格来说并不算是一种,相对于第一种方法来说只是简化了代码) PS:有些文章提到了foreach+indexOf数组去重的方法,个人觉得都是大同小异,所以没有写上去。 原文发布时间为:2018-10-15 本文作者:沉静地闪光 本文来自云栖社区合作伙伴“编程微刊”,了解相关信息可以关注“编程微刊”。

优秀的个人博客,低调大师

Python全栈 Web(JavaScript 数组、string、正则、Math、Date)

数组: 常用的API: toString() 将数组转换为字符串 默认是将数组的元素 使用逗号隔开 链接成字符串在进行返回 join(seperator) 将数组的元素使用seperator字符串作为分隔符 链接成字符串再进行返回 reverse() 将数组进行反转 该函数会改变现有数组的结构 不需要接受返回值 sort() 对数组的元素进行排序 默认按照Unicode码进行排序 对数字不准确 会改变原有数组的内容 特点: 允许自定义的排序规则(排序函数)用来指定数组的排序方式 语法: arr.sort(排序函数); 排序函数: 升序的排序函数: function sortAsc(a, b){ return a - b; } arr.sort(sortAsc); 匿名函数实现: arr.sort(function(a, b){ return a - b; }) 降序排序: 排序后

优秀的个人博客,低调大师

JavaScript函数式编程之pointfree与声明式编程

更多相关内容见博客 github.com/zhuanyongxi… 函数式编程中的pointfree的意思就是“无参”或“无值”,pointfree style是一种编程范式,也作tacit programming,就是“无参编程”的意思了。什么是“无参编程”? // 这就是有参的,因为有word var snakeCase = word => word.toLowerCase().replace(/\s+/ig, '_'); // 这是pointfree var snakeCase = compose(replace(/\s+/ig, '_'), toLowerCase); 从另一个角度看,有参的函数的目的是得到一个数据,而pointfree的函数的目的是得到另一个函数。 所以,如下的方程,虽然也有参,也可以认为是pointfree的。 const titlesForYear = year => pipe( filter(publishedInYear(year)), map(book => book.title) ) 那这pointfree有什么用? 它可以让我们把注意力集中在函数上,参数命名的麻烦肯定是省了,代码也更简洁优雅。 需要注意的是,一个pointfree的函数可能是由众多非pointfree的函数组成的,也就是说底层的基础函数大都是有参的,pointfree体现在用基础函数组合而成的高级函数上。如果我们使用函数式编程的工具,如ramda,这些基础函数大都已经被写好了,这样我们去写pointfree的代码就很容易了。 什么是声明式编程?它区别于命令式编程 // 命令式 var words = []; for (i = 0; i < otherWords.length; i++) { words.push(otherWords[i].word); } // 声明式 var words = otherWords.map(function(ele){ return ele.word; }); 容易看出,命令式的代码,我们不但要去遍历,还要关注如何遍历。而声明式的就容易很多,可以节省我们的注意力,代码也更加简洁。 其他的命令式的写法有:使用ifelse进行的条件判断,使用算数运算符进行的算数运算,使用比较运算符进行的比较运算和使用逻辑运算符进行的逻辑运算。 至于那些说“虽然如此,但使用命令式循环速度要快很多”的人,我建议你们先去学学 JIT 优化代码的相关知识。这里有一个非常棒的视频,可能会对你有帮助。 需要注意的是,要实现这种声明式的编程,首先我们要有这个map方法,这一点与pointfree相同,都是需要我们先对常用的操作做一次封装,而这些常用的操作本身还是命令式的。 pointfree的声明式代码是函数式编程应该有的样子。 最后用一个来自Scott Sauyet的文章《Favoring Curry》中的例子,使用的函数式工具是ramda。下面的代码不需要一句一句的看,大概体会一下就可以了。 一组JSON数据 var data = { result: "SUCCESS", interfaceVersion: "1.0.3", requested: "10/17/2013 15:31:20", lastUpdated: "10/16/2013 10:52:39", tasks: [ {id: 104, complete: false, priority: "high", dueDate: "2013-11-29", username: "Scott", title: "Do something", created: "9/22/2013"}, {id: 105, complete: false, priority: "medium", dueDate: "2013-11-22", username: "Lena", title: "Do something else", created: "9/22/2013"}, {id: 107, complete: true, priority: "high", dueDate: "2013-11-22", username: "Mike", title: "Fix the foo", created: "9/22/2013"}, {id: 108, complete: false, priority: "low", dueDate: "2013-11-15", username: "Punam", title: "Adjust the bar", created: "9/25/2013"}, {id: 110, complete: false, priority: "medium", dueDate: "2013-11-15", username: "Scott", title: "Rename everything", created: "10/2/2013"}, {id: 112, complete: true, priority: "high", dueDate: "2013-11-27", username: "Lena", title: "Alter all quuxes", created: "10/5/2013"} // , ... ] }; 需求是找到Scott所有未完成的任务,并按照到期日期升序排列。 正确的结果是 [ {id: 110, title: "Rename everything", dueDate: "2013-11-15", priority: "medium"}, {id: 104, title: "Do something", dueDate: "2013-11-29", priority: "high"} ] 命令式的代码如下 getIncompleteTaskSummaries = function(membername) { return fetchData() .then(function(data) { return data.tasks; }) .then(function(tasks) { var results = []; for (var i = 0, len = tasks.length; i < len; i++) { if (tasks[i].username == membername) { results.push(tasks[i]); } } return results; }) .then(function(tasks) { var results = []; for (var i = 0, len = tasks.length; i < len; i++) { if (!tasks[i].complete) { results.push(tasks[i]); } } return results; }) .then(function(tasks) { var results = [], task; for (var i = 0, len = tasks.length; i < len; i++) { task = tasks[i]; results.push({ id: task.id, dueDate: task.dueDate, title: task.title, priority: task.priority }) } return results; }) .then(function(tasks) { tasks.sort(function(first, second) { var a = first.dueDate, b = second.dueDate; return a < b ? -1 : a > b ? 1 : 0; }); return tasks; }); }; pointfree的代码 var getIncompleteTaskSummaries = function(membername) { return fetchData() .then(R.prop('tasks')) .then(R.filter(R.propEq('username', membername))) .then(R.reject(R.propEq('complete', true))) .then(R.map(R.pick(['id', 'dueDate', 'title', 'priority']))) .then(R.sortBy(R.prop('dueDate'))); }; pointfree的声明式的代码 // 提取 tasks 属性 var SelectTasks = R.prop('tasks'); // 过滤出指定的用户 var filterMember = member => R.filter( R.propEq('username', member) ); // 排除已经完成的任务 var excludeCompletedTasks = R.reject(R.propEq('complete', true)); // 选取指定属性 var selectFields = R.map( R.pick(['id', 'dueDate', 'title', 'priority']) ); // 按照到期日期排序 var sortByDueDate = R.sortBy(R.prop('dueDate')); // 合成函数 var getIncompleteTaskSummaries = function(membername) { return fetchData().then( R.pipe( SelectTasks, filterMember(membername), excludeCompletedTasks, selectFields, sortByDueDate, ) ); }; 参考文章 Pointfree编程风格指南 Favoring Curry JS函数式编程指南 Tacit programming Thinking in Ramda: Pointfree Style Thinking in Ramda: Declarative Programming 原文发布时间为:2018年06月17日 原文作者:砖用冰西瓜 本文来源:掘金如需转载请联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册