数组方法概述

1、不改变原数组,返回新数组
  • concat()

    连接两个或多个数组,两边的原始数组都不会变化,返回被连接数组的一个副本。

  • join()

    把数组中所有元素放入一个字符串中,返回字符串。

  • slice()

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

  • map()

    创建一个新数组并返回,其中新数组的每个元素由调用原始数组中的每一个元素执行提供的函数得来,原始数组不会改变。

  • every()

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

  • some()

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

  • filter()

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

2、改变原数组
  • forEach()

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

  • pop()

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

  • push()

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

  • reverse()

    颠倒数组中元素的位置,返回该数组的引用。

  • shift()

    从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

  • unshift()

    将一个或多个元素添加到数组的开头,并返回新数组的长度。

  • sort()

    对数组的元素进行排序,并返回数组。排序不一定是稳定的。默认排序顺序是根据字符串Unicode码点。

  • splice()

    向数组中添加/删除项目,然后返回被删除项目的新数组。

遍历方法

获取属性名:for..in 和 object.keys()的区别
  • for..in语句:遍历对象的可枚举属性名列表,包括[[Prototype]]原型链。

    • 对于数组,不仅会包含所有数值索引,还会包含所有可枚举属性。遍历数组使用传统for循环
  • propertyIsEnumerable(..):只检查属性名是否在对象中并且enumerable:true
  • Object.keys(..):只查找属性名是否在对象中,返回一个数组,包含所有可枚举属性名。
  • Object.getOwnPropertyNames(..):只查找属性名是否在对象中,返回一个数组,包含所有属性名,无论是否可枚举。
获取属性值:for..ofobject.values()
  • for..of语句:遍历可迭代对象的可枚举属性的值列表,包括[[Prototype]]原型链。
  • 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"]]

两个升序数组合并成一个升序数组

  • 时间复杂度 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++]);
} return result.concat(left.slice(il)).concat(right.slice(ir));
}
  • 时间复杂度 O(M+N) ,空间复杂度 O(1)
public class Solution {
// m, n 是数组长度
public void merge(int[] nums1, int m, int[] nums2, int n) {
int i = m - 1, j = n - 1, writeIdx = m + n - 1;
while (i >= 0 && j >= 0)
nums1[writeIdx--] = nums1[i] > nums2[j]? nums1[i--] : nums2[j--];
while (j >= 0)
nums1[writeIdx--] = nums2[j--];
}
}

数组去重

  • 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]
  • 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]

多维数组降维

const flattenDeep = arr => Array.isArray(arr)
? arr.reduce( (a, b) => [...a, ...flattenDeep(b)] , [])
: [arr] flattenDeep([1, [[2], [3, [4]], 5]]); // [1, 2, 3, 4, 5]

两个数组的交集 II

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

例如:

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

注意:

  • 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
  • 我们可以不考虑输出结果的顺序。

跟进:

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果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 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 {number}
*/
var singleNumber = function(nums) { let number = 0;
for(let i = 0; i < nums.length; i++) {
number ^= nums[i];
}
return number;
};

参考资料:https://blog.csdn.net/qq_35546040/article/details/80284079

两数之和

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

解法:

/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) { var map = new Map();
var number = []; for(var i = 0; i < nums.length; i ++) { if(map.has(target - nums[i])) {
number.push(i, map.get(target - nums[i]));
break;
}
map.set(nums[i], i);
}
return number;
};

参考资料:http://www.cnblogs.com/grandyang/p/4130379.html

旋转数组

给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

示例 1:

输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]

说明:

  • 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
  • 要求使用空间复杂度为 O(1) 的原地算法。

解法:

/**
* @param {number[]} nums
* @param {number} k
* @return {void} Do not return anything, modify nums in-place instead.
*/
var rotate = function(nums, k) { var k = k % nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, k, nums.length - 1);
reverse(nums, 0, k - 1);
}; var reverse = function(nums, i, j) { while(i < j) {
swap(nums, i++, j--);
}
} var swap = function(nums, i, j) {
var temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}

参考资料:https://segmentfault.com/a/1190000003705446

加一

给定一个非负整数组成的非空数组,在该数的基础上加一,返回一个新的数组。

最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:

输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。

示例 2:

输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。

解法:

/**
* @param {number[]} digits
* @return {number[]}
*/
var plusOne = function(digits) { if(digits.length == 0) return digits;
var carry = 1;
var res = [1]; for(var i = digits.length - 1; i >= 0; i--) { if(carry == 0) return digits;
var sum = carry + digits[i];
digits[i] = sum % 10;
carry = parseInt(sum / 10);
} for(let i = digits.length - 1; i >= 0; i--) {
res.push(0);
} return carry == 0 ? digits : res; };

参考资料:http://www.cnblogs.com/grandyang/p/4079357.html

存在重复

给定一个整数数组,判断是否存在重复元素。

如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。

示例 1:

输入: [1,2,3,1]
输出: true

示例 2:

输入: [1,2,3,4]
输出: false

示例 3:

输入: [1,1,1,3,3,4,3,2,4,2]
输出: true

解法 :

/**
* @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;
};

移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

说明:

  1. 必须在原数组上操作,不能拷贝额外的数组。
  2. 尽量减少操作次数。

解法1:

/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
let moveZeroes = function(nums) { let n = nums.length;
let slow = -1; // 指针索引
let fast = 0; // 指针索引
let x = 0; while(slow < fast && fast < n) { if (nums[fast] != x) {
slow ++;
swap(nums, slow, fast);
}
fast ++;
}
}; let swap = function(nums, i, j) {
let temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}

解法2:

/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
let moveZeroes = function(nums) { let n = nums.length;
let one = 0;
let x = 0; for(let i = 0; i < n; i ++) { if (nums[i] != x) {
nums[one ++] = nums[i];
}
} for(let i = one; i < n; i ++) {
nums[i] = x;
}
};

原文链接:https://github.com/yygmind/blog/issues/4

js 常见数组算法的更多相关文章

  1. JS常见排序算法

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. JS常见的算法

    原文链接:Jack Pu's Blog 虽说我们很多时候前端很少有机会接触到算法.实际上学习数据结构与算法对于工程师去理解和分析问题都是有帮助的.如果将来当我们面对较为复杂的问题,这些基础知识的积累可 ...

  3. JS中几种常见的数组算法(前端面试必看)

    JS中几种常见的数组算法 1.将稀疏数组变成不稀疏数组 /** * 稀疏数组 变为 不稀疏数组 * @params array arr 稀疏数组 * @return array 不稀疏的数组 */ f ...

  4. 常见排序算法(JS版)

    常见排序算法(JS版)包括: 内置排序,冒泡排序,选择排序,插入排序,希尔排序,快速排序(递归 & 堆栈),归并排序,堆排序,以及分析每种排序算法的执行时间. index.html <! ...

  5. Java基础语法(8)-数组中的常见排序算法

    title: Java基础语法(8)-数组中的常见排序算法 blog: CSDN data: Java学习路线及视频 1.基本概念 排序: 是计算机程序设计中的一项重要操作,其功能是指一个数据元素集合 ...

  6. 常见排序算法原理及JS代码实现

    目录 数组 sort() 方法 冒泡排序 选择排序 插入排序 希尔排序 归并排序 堆排序 快速排序 创建时间:2020-08-07 本文只是将作者学习的过程以及算法理解进行简单的分享,提供多一个角度的 ...

  7. JavaScript版几种常见排序算法

    今天发现一篇文章讲“JavaScript版几种常见排序算法”,看着不错,推荐一下原文:http://www.w3cfuns.com/blog-5456021-5404137.html 算法描述: * ...

  8. JS数据结构与算法-概述

    JS数据结构与算法概述 数据结构: 计算机存储, 组织数据的方式, 就像锅碗瓢盆 算法: 一系列解决问题的清晰指令, 就像食谱 两者关系: 程序 = 数据结构 + 算法 邂逅数据结构与算法 什么是数据 ...

  9. 常见排序算法(附java代码)

    常见排序算法与java实现 一.选择排序(SelectSort) 基本原理:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换:接着对不包括第一个记录以外的其他 ...

随机推荐

  1. Charles4.2.8抓包(http+https)

    Charles 和 Fiddler 一样都是http抓包工具. 之前用 Fiddler 抓个别 ios 手机 https 报文时总卡在哪里返不回任何数据,后来怀疑是 Fiddler 问题,就考虑使用  ...

  2. -Dmaven.test.skip=true 和 -DskipTests

    -DskipTests,不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下. -Dmaven.test.skip=true,不执行测试用例,也不编译测试 ...

  3. COGS 有标号的DAG/强连通图计数

    COGS索引 一堆神仙容斥+多项式-- 有标号的DAG计数 I 考虑\(O(n^2)\)做法:设\(f_i\)表示总共有\(i\)个点的DAG数量,转移考虑枚举DAG上所有出度为\(0\)的点,剩下的 ...

  4. The three day 给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本

    """ 给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本. 所谓无效化 IP 地址,其实就是用 "[.]" 代替了每个 ...

  5. c# 获取网页的爬虫程序

    转载于:https://www.cnblogs.com/wzk153/p/9145684.html HtmlAgilityPack相关详解: https://www.cnblogs.com/asxin ...

  6. 微信小程序自定义组件,提示组件

    微信小程序自定义组件,这里列举了一个常用的提示自定义组件,调用自定义组件中的方法和字段.仅供参考和学习. 编写组件: 在根目录下添加“components”目录,然后像添加Page页面一样添加自定义组 ...

  7. Java 环境

    1. Java 环境1999年发布第二代java平台 简称 Java2 标准版 Standard Edition J2SE 企业版 Enterprise Edition J2EE 微型版 Micro ...

  8. 报告题目:HAO智能:HI + AI + OI

     报告题目:HAO智能:HI + AI + OI 报告摘要:大数据面向异构自治的多源海量数据, 旨在挖掘数据间复杂且演化的关联.大数据知识工程(BigKE)从大数据的 HACE定理开始, 从大知识建模 ...

  9. 每周分享五个 PyCharm 使用技巧(六)

    大家好,今天我又来给大家更新 PyCharm 的使用技巧. 从今年3月24号开始一直到今天,将近四个月的时间.包括本篇,一共更新了6篇文章,每篇 5 个小技巧,总计 30 个. 这30个使用技巧,全部 ...

  10. 【洛谷 P5341】 [TJOI2019]甲苯先生和大中锋的字符串(后缀自动机)

    题目链接 建出\(sam\),求出parent tree上每个点的\(endpos\)集合大小. 如果等于\(k\),说明到达这个点的都可以.给\((len[fa(i)],len[i]]\)的\(cn ...