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 相关文章推荐
js 刷新页面的代码小结 推荐
Apr 02 Javascript
基于JavaScript 数据类型之Boolean类型分析介绍
Apr 19 Javascript
js实现touch移动触屏滑动事件
Apr 17 Javascript
jQuery中trigger()与bind()用法分析
Dec 18 Javascript
jQuery添加options点击事件并传值实例代码
May 18 Javascript
关于Function中的bind()示例详解
Dec 02 Javascript
JavaScript原生数组Array常用方法
Apr 06 Javascript
AngularJS实现根据不同条件显示不同控件
Apr 20 Javascript
React学习笔记之列表渲染示例详解
Aug 22 Javascript
Jquery Datatables的使用详解
Jan 30 jQuery
JavaScript位置参数实现原理及过程解析
Sep 14 Javascript
jQuery实现全选按钮
Jan 01 jQuery
详解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判断变量的函数
2012/04/24 PHP
php生成二维码
2015/08/10 PHP
PHP编程中的__clone()方法使用详解
2015/11/27 PHP
lnmp安装多版本PHP共存的方法详解
2018/08/02 PHP
PHP利用Mysql锁解决高并发的方法
2018/09/04 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
2019/11/23 PHP
将HTML自动转为JS代码
2006/06/26 Javascript
关于JavaScript的gzip静态压缩方法
2007/01/05 Javascript
Prototype使用指南之hash.js
2007/01/10 Javascript
基于jquery的图片懒加载js
2010/06/30 Javascript
瀑布流布局并自动加载实现代码
2013/03/12 Javascript
js正则表达exec与match的区别说明
2014/01/29 Javascript
浅析基于WEB前端页面的页面内容搜索的实现思路
2014/06/10 Javascript
理解javascript中的回调函数(callback)
2014/09/02 Javascript
jQuery中;function($,undefined) 前面的分号的用处
2014/12/17 Javascript
JavaScript实现查找字符串中第一个不重复的字符
2014/12/29 Javascript
JavaScript实现动画打开半透明提示层的方法
2015/04/21 Javascript
jQuery Easyui Datagrid实现单行的上移下移及保存移动的结果
2016/08/15 Javascript
前端实现文件的断点续传(前端文件提交+后端PHP文件接收)
2016/11/04 Javascript
AngularJS学习笔记(三)数据双向绑定的简单实例
2016/11/08 Javascript
Angular2 PrimeNG分页模块学习
2017/01/14 Javascript
JS中判断某个字符串是否包含另一个字符串的五种方法
2018/05/03 Javascript
layui实现左侧菜单点击右侧内容区显示
2019/07/26 Javascript
如何在Vue中抽离接口配置文件
2019/10/31 Javascript
nodejs实现UDP组播示例方法
2019/11/04 NodeJs
JS插入排序简单理解与实现方法分析
2019/11/25 Javascript
在Vue中使用Echarts可视化库的完整步骤记录
2020/11/18 Vue.js
基于python 二维数组及画图的实例详解
2018/04/03 Python
如何安装并使用conda指令管理python环境
2019/07/10 Python
这可能是最好玩的python GUI入门实例(推荐)
2019/07/19 Python
7款设计巧妙的css3飘带状3D立体效果的导航菜单和表单窗口
2013/02/04 HTML / CSS
广州盈通面试题
2015/12/05 面试题
汽车销售求职自荐信
2013/10/01 职场文书
学校机关党总支领导班子整改工作方案
2014/10/26 职场文书
初三语文教学计划
2015/01/22 职场文书
python中subplot大小的设置步骤
2021/06/28 Python