javascript中数组的常用算法深入分析


Posted in Javascript onMarch 12, 2019

前言

Array是Javascript构成的一个重要的部分,它可以用来存储字符串、对象、函数、Number,它是非常强大的。因此深入了解Array是前端必修的功课。本文将给大家详细介绍了javascript中数组的常用算法,下面话不多说了,来一起看看详细的介绍吧

一、不改变原数组,返回新数组(字符串)

1、concat()   连接两个或者多个数组,两边的原始数组都不会变化,返回的是被连接数组的一个副本。

2、join()  把数组中所有的元素放入到一个字符串中,返回字符串

var a = [1,2,3];
a.join([4,5,6]); // "14,5,624,5,63"
a.join('sau');  // "1sau2sau3"

3、slice()    从开始到结束(不包括结束)选择数组的一部分浅拷贝到一个新数组

var a = [1,2,3,4,5];
a.slice(0,0);  //[]
a.slice(0,1);  //[1]
a.slice(2,4); //[3,4]
a.slice(0,5); //[1,2,3,4,5]
a.slice(10,1); //[]
a.slice(4); //[5]

4、map()   创建一个新的数组并返回,其中新数组的每一个元素由调用原始数组中的每一个元素执行提供的函数得来,原数组不变

5、every()  对数组中的每一个元素都执行一次指定的回调函数,直到回调函数返回false,此时every()返回false并不再继续执行,如果回调函数都对每一个元素都返回true,那么every()返回true。

6、some()  对数组中的每一个元素都执行一次指定的回调函数,直到回调函数返回true,此时some()返回true并不再执行。如果回调函数对每一个元素都返回false,那么some()将返回false。

7、filter()   创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。

二、改变原数组

1、forEach()   针对每一个元素执行提供的函数。会修改原来的数组,不会返回执行结果,返回undefined。

2、pop()   删除数组最后一个元素,返回被删除的元素的值,如果数组为空,则不改变数组,返回undefined。

3、push()   向数组末尾添加一个或多个元素,返回改变后数组的长度。

4、reverse()   颠倒数组中元素的位置,返回该数组的引用。

5、shift()   从数组中删除第一个元素,改变原数组,并返回该元素的值。

6、unshift()   将一个或者多个元素添加到数组的开头,并返回新数组的长度。

7、sort()   对数组的元素进行排序,返回数组。排序不一定是稳定的。默认排序顺序是根据字符串unicode码点。

8、splice()   向数组中添加/删除元素,然后返回被删除的新数组()。

var a = [1,2,3,4,5];
a.splice(0,1);  //删除从0位置开始的1个 返回[1] a为[2,3,4,5] 
a.splice(1,0,99) //在1的位置插入99 [2,99,3,4,5]
a.splice(1,1,88) //99替换为88 [2,88,3,4,5]

三、遍历方法

1、获取属性名:for...in  和object.key()的区别

答:1、for in 遍历对象可以枚举的属性名列表,包括[[prototype]]原型链;

2、Object.keys() 只查找属性名是否在对象中,返回一个数组,包含所有可以枚举的属性名;

3、Object.getOwnPropertyNames()只查找属性名是否在对象中,返回一个数组,包含所有的属性名,不论是否可枚举。

2、获取属性值: for... of 和object.values()

for of 语句:遍历可迭代对象的可枚举属性值列表,包括[[propertype]]原型链;

object.values() :返回一个给定对象自身的所有可枚举属性的值,不包括原型链。

四、ES6语法Map键值对转化为数组

new Map创建一个map

// new Map创建一个map
let map = new Map([[1,"one"], [2,"two"], [3,"three"]]);
map.set(4, "four");

// 获取所有键值对
console.log("获取key")
console.log([...map.keys()]) // 输出[1, 2, 3, 4]

console.log("获取value")
console.log([...map.values()]) // 输出[one, two, three, four]

console.log("获取map数组")
console.log([...map]) // 输出[[1, "one"], [2, "two"], [3, "three"], [4, "four"]]

五、两个升序的数组合并成一个升序数组

1、时间复杂度O(M+N),空间复杂度O(M+N)

function merge(left, right){
 let result = [],
  il  = 0,
  ir  = 0;

 while (il < left.length && ir < right.length) {
  result.push(left[il] < right[ir] ? left[il++] : right[ir++]);
console.log(result);
 }

 return result.concat(left.slice(il)).concat(right.slice(ir));
}

2、时间复杂度O(M+N),空间复杂度O(1)

// m, n 是数组长度
function merge(left, m, right, n) {
 var i = m - 1, j = n - 1, writeIdx = m + n - 1;
 while (i >= 0 && j >= 0)
 left[writeIdx--] = left[i] > right[j]? left[i--] : right[j--];
 while (j >= 0)
 left[writeIdx--] = right[j--];
 return left;
}

六、数组重复问题

(一)数组去重

1、reduce方法

const distinct = arr => arr.sort().reduce( (init, current) => {
 
 if (init.length === 0 || init[init.length - 1] !== current) {
  init.push( current );
 }
 return init;
}, []);

let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
distinct(arr); // [1, 2, 3, 4, 5]

2、filter方法

const distinct = arr => arr.filter( (element, index, self) => {
 return self.indexOf( element ) === index;
});

let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
distinct(arr); // [1, 2, 3, 5, 4]

(二)排序数组去重

/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
 
 if(!nums || nums.length == 0) return 0;
 
 let len = 0;
 for(let i = 1; i < nums.length; i++) {
  if (nums[len] != nums[i]) {
   nums[++ len] = nums[i];
  }
 }
 return len + 1;
};

(三)判断数组是否存在重复

/**
 * @param {number[]} nums
 * @return {boolean}
 */
var containsDuplicate = function(nums) {
 
 let hashMap = new Map();
 for(let i = 0; i < nums.length; i++) {
  
  if( hashMap.has(nums[i]) ) {
   return true;
  }
  
  hashMap.set(nums[i], 1);
 }
 
 return false;
};

七、两个数组的交集

给定两个数组,写一个方法来计算它们的交集。

例如:

给定 nums1 = [1, 2, 2, 1], nums2 = [2, 2], 返回 [2, 2].

注意:1、出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。2、

我们可以不考虑输出结果的顺序。

跟进:1、如果给定的数组已经排好序呢?你将如何优化你的算法?2、如果 nums1 的大小比 nums2 小很多,哪种方法更优?3、如果nums2的元素存储在磁盘上,内存是有限的,你不能一次加载所有的元素到内存中,你该怎么办?

解法:

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
 
 var map1 = new Map();
 var number = [];
 
 for(var i = 0; i < nums1.length; i++) {
  var map1Value = map1.get(nums1[i]);
  map1.set( nums1[i], ( map1Value ? map1Value : 0 ) + 1 );
 }
 
 for(var i = 0; i < nums2.length; i++) {
  if( map1.has(nums2[i]) && map1.get(nums2[i]) != 0 ) {
   number.push(nums2[i]);
   map1.set( nums2[i], map1.get(nums2[i]) - 1 );
  }
 }
 
 return number;
};

八、找出一个数组中只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
 
 let number = 0;
 for(let i = 0; i < nums.length; i++) {
  number ^= nums[i];
 }
 return number;
};

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jQuery的deferred对象使用详解
Aug 20 Javascript
angular双向绑定模拟探索
Dec 26 Javascript
Angular2里获取(input file)上传文件的内容的方法
Sep 05 Javascript
JS中的多态实例详解
Oct 15 Javascript
浅析JS中回调函数及用法
Jul 25 Javascript
JavaScript创建对象方法实例小结
Sep 03 Javascript
jQuery序列化form表单数据为JSON对象的实现方法
Sep 20 jQuery
Vue Prop属性功能与用法实例详解
Feb 23 Javascript
koa2 从入门到精通(小结)
Jul 23 Javascript
vue中的使用token的方法示例
Mar 10 Javascript
Vue 中获取当前时间并实时刷新的实现代码
May 12 Javascript
原生Js 实现的简单无缝滚动轮播图的示例代码
May 10 Javascript
详解javascript 变量提升(Hoisting)
Mar 12 #Javascript
NestJs 静态目录配置详解
Mar 12 #Javascript
JavaScript使用小插件实现倒计时的方法讲解
Mar 11 #Javascript
30分钟精通React今年最劲爆的新特性——React Hooks
Mar 11 #Javascript
记录一次完整的react hooks实践
Mar 11 #Javascript
es6数值的扩展方法
Mar 11 #Javascript
Vue实现一个图片懒加载插件
Mar 11 #Javascript
You might like
如何使用php输出时间格式
2013/08/31 PHP
PHP中filter函数校验数据的方法详解
2015/07/31 PHP
php文件上传类的分享
2017/07/06 PHP
ASP中用Join和Array,可以加快字符连接速度的代码
2007/08/22 Javascript
javascript向后台传送相同属性的参数即数组参数
2014/02/17 Javascript
JavaScript实现的使用键盘控制人物走动实例
2014/08/27 Javascript
ajax+jQuery实现级联显示地址的方法
2015/05/06 Javascript
设计模式中的组合模式在JavaScript程序构建中的使用
2016/05/18 Javascript
文本框只能输入数字的实现方法(兼容IE火狐)
2016/06/25 Javascript
仿Angular Bootstrap TimePicker创建分钟数-秒数的输入控件
2016/07/01 Javascript
JS中的数组方法笔记整理
2016/07/26 Javascript
解决前端跨域问题方案汇总
2016/11/20 Javascript
Vue入门之数据绑定(小结)
2018/01/08 Javascript
详解Vue的常用指令v-if, v-for, v-show,v-else, v-bind, v-on
2018/10/12 Javascript
vue配置接口域名方法总结
2019/05/12 Javascript
微信小程序实现上传图片裁剪图片过程解析
2019/08/22 Javascript
深入了解JavaScript 防抖和节流
2019/09/12 Javascript
[54:45]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 Optic vs OG
2018/04/02 DOTA
Python深入学习之内存管理
2014/08/31 Python
深入理解Python中各种方法的运作原理
2015/06/15 Python
Python 爬虫模拟登陆知乎
2016/09/23 Python
Python 专题六 局部变量、全局变量global、导入模块变量
2017/03/20 Python
python整小时 整天时间戳获取算法示例
2019/02/20 Python
Python 限制线程的最大数量的方法(Semaphore)
2019/02/22 Python
PyQtGraph在pyqt中的应用及安装过程
2019/08/04 Python
matlab中imadjust函数的作用及应用举例
2020/02/27 Python
pytorch下的unsqueeze和squeeze的用法说明
2021/02/06 Python
TensorFlow2.0使用keras训练模型的实现
2021/02/20 Python
数据库什么时候应该被重组
2012/11/02 面试题
GWT都有什么特性
2016/12/02 面试题
文艺晚会策划方案
2014/06/11 职场文书
应届生简历自我评价
2015/03/11 职场文书
2015年销售员工作总结范文
2015/04/07 职场文书
公司财务管理制度
2015/08/04 职场文书
php png失真的原因及解决办法
2021/11/17 PHP
MYSQL事务的隔离级别与MVCC
2022/05/25 MySQL