数组 Array
arr=[]、null、undefined 打印arr?.length分别输出 0、undefined、undefined
会改变原数组:
arrLen = arr.push(2, 3) //向数组末尾添加一个或多个元素,并返回修改后数组的长度
arrLen = arr.unshift(2, 3) //向数组开头添加一个或多个元素,并返回修改后数组的长度
delElemt = arr.shift() //删除数组中第一个元素, 并返回被删除元素
delElemt = arr.pop() //删除数组最后一个元素, 并返回被删除元素
delArr = arr.splice(index, num) // (索引,个数) 删除第index开始的num个元素,并返回删除的数组、arr.splice(indexA, num, b); --可以用这个在原数组索引为A的数据替换为数据b
eg: arr.splice(2, 1, 'a', 'b'); //arr = [1, 2, 3, 4, 5];
// 从索引2开始删除1个元素,然后添加'a'和'b',arr变为 [1, 2, 'a', 'b', 4, 5]
如果要在原数组某个位置插入某个元素可以:arr.splice(index, 0, xxx);
arr.reverse() //颠倒数组中元素的顺序
arr.sort() //数组中的元素按照首字母顺序排序arr.fill(fillItem, start, end) // 从索引start到end填充 fillItem
arr3.sort((a, b) => a - b) //若 a < b, 则 a - b 是一个负数, 表示 a 应该在 b 前面——数组中的元素按照数字排序其他:
arr = [...str] //使用扩展运算符将 字符串 转换为 数组——扩展运算符是用于展开可迭代对象(如数组、字符串等)
[A, ...B] = [1, 2, 3, 4, 5, 6] //数组解构+扩展运算符
[x, y] = [y, x] //两数交换——//前一行不加分号; 会报错arr.flatMap(x => [x, x * 2]) // [1, 2, 2, 4, 3, 6],flatMap代替reduce和concat:
let arr = [1, 2, 3]
等价于:(👇劣势:在每次迭代创建一个必须被垃圾回收的临时数组,并且是将元素从当前的累加器数组复制到一个新的数组中,而不是将新的元素添加到现有的数组中)
arr.reduce((acc, x) => acc.concat([x, x * 2]), []) // [1, 2, 2, 4, 3, 6]
str = arr.join(分隔符) // 将所有元素放入一个字符串,用指定分隔符分隔
flag = arr.includes(XX) //判断数组中是否包含某个值,返回布尔值
不会改变原数组:
newArr = arr1.concat(arr2, 2, 3) // 将多个数组或值合并为一个新数组
newArr = arr.slice(start, end); // 截取从索引[start,end)的子数组,string类型也可用
newArr = arr,flat(); // 将嵌套数组平展开,默认展开一层 flat(指定展开深度层数n)
数组的10种遍历方式汇总(都不改变原数组):
for(letitem ofarr) // item, ES6新增,可用于 arr、string、map、set
for(let i = 0; i < arr.length; i++) // arr[i]
for(leti inarr) // arr[i]
arr.forEach((item, index) => {}) //会跳过undefined的元素,不影响原数组,不能return
newArr = arr.map((item, index) => {}) // 会返回新数组,能return
性能上:for>forEach>map,定长或长度无需计算时用for,forEach有参数及上下文执行可能拖慢性能,map数组创建及赋值产生性能开销大
newArr = arr.filter((value, index) => { return XX }) //筛选符合条件的元素, 返回一个新数组
newArr = arr.filter((item)=> item?.status !== 'x')//过滤掉状态等于x的数据
sum = arr.reduce((total, value, index) => { return total+value }, 0) // 迭代(累加)器,如果没有提供初始累积值,数组第一个元素将作为初始累积值,从第二个元素开始迭代,若数组为空且没有提供初始值,会抛出typeError异常
flag = arr.every((item, index) => { }) // 有返回值,检查数组每个值是否满足指定条件,若有一个不满足则返回false,剩余值不再继续遍历;若都满足返回true
flag = arr.some((item, index) => { }) // 有返回值,检查数组每个值是否满足指定条件,有一个满足则返回true,剩余值不再继续遍历;若都不满足返回false
every和some可以作为if条件判断,if(arr.every( (item) =>{return item?.satus=='x';}) )
num = arr.find((item) => item === '***') // 找到符合条件的元素返回,遍历完没有符合条件的则返回undefined
index= arr.findIndex((item) => item === '***') // 找到符合条件的元素下标返回,遍历完没有符合条件的则返回-1
index= arr.indexOf(item) // 找到符合条件的元素下标返回,遍历完没有符合条件的则返回-1
遍历数组,可进行中断循环:
(1)传统for循环,break中断:for (let i = 0; i < arr.length; i++)
(2)some方法:arr.some((value, index) => {满足某个条件就返回true});
(3)for...of/in 循环,break中断:for (const value of arr) 、for(let index in arr)
(4)forEach,但需要抛出异常中断,不建议:
try { arr.forEach((value, index) => { if (***) { throw new Error('停止循环'); // 抛出异常以停止循环 } }); } catch (e) { if (e.message !== '停止循环') throw e; // 如果不是我们的停止指令,则重新抛出异常 }(forEach、map、filter目前无法停止遍历)
比较数组A和B是否相同:
(1)方法一:JSON.stringify()----→顺序和类型完全相同,有对象易出错
const isEqual = JSON.stringify(arrayA) === JSON.stringify(arrayB);
(2)方法二:数组every方法+长度判断 ----→元素对应且相等
const isEqual= arrayA.length === arrayB.length && arrayA.every((item, index) => item=== arrayB[index]);
(3)方法三:数组sort方法+JSON.stringify()----→顺序可以不同
const sortedArray1 = arrayA.slice().sort(); // 复制并排序 const sortedArray2 = arrayB.slice().sort(); // 复制并排序 const isEqual = JSON.stringify(sortedArray1) === JSON.stringify(sortedArray2);(4)方法四:lodash的isEqual方法 ----→数组中包含对象或数组也适用
import _ from 'lodash'
const isEqual= _.isEqual(arrayA, arrayB);
如果要查数组A和B的不同:
(1)方法一:filter+includes
// 找出在arrayA中但不在arrayB中的元素 const deletedItems = arrayA.filter(item => !arrayB.includes(item)); // 找出在arrayB中但不在arrayA中的元素 const addedItems = arrayB.filter(item => !arrayA.includes(item));(2)方法二:set
// 将数组转换为Set以便于操作 const setA = new Set(arrayA); const setB = new Set(arrayB); // 找出在setA中但不在setB中的元素 const deletedItems = Array.from(setA).filter(item => !setB.has(item)); // 找出在setB中但不在setA中的元素 const addedItems = Array.from(setB).filter(item => !setA.has(item));(3)方法三:reduce+map
// 将数组转换为Map,以便快速查找和比较 const mapA = new Map(arrayA.map(item => [item.id, item])); const mapB = new Map(arrayB.map(item => [item.id, item])); // 找出在mapA中但不在mapB中的元素(基于ID) const deletedItems = Array.from(mapA.keys()).filter(id => !mapB.has(id)).map(id => mapA.get(id)); // 找出在mapB中但不在mapA中的元素(基于ID) const addedItems = Array.from(mapB.keys()).filter(id => !mapA.has(id)).map(id => mapB.get(id));判断数组存在且不为[]:
(1)if (!arr?.length) //arr为null或undefined,arr为[]都会进入if
(2)if(!arr || arr.length==0) //arr为空或[]都会进入if
(3)if(arr && arr.length>0) //arr存在且长度大于0就一定有数据
求数组最大值方法(同理也可求最小):
(1)const max =Math.max(...arr); //适用于元素数量不是特别大
(2)const max = arr.reduce((a, b) =>Math.max(a, b)); //迭代每次返回最大
(3)const max =Math.max.apply(null, arr); //处理大量数据时比 (1) 扩展运算符高效
(4)const max = arr.sort((a, b) => b - a)[0]; //改变了原数组顺序,建议复制数组
(5)遍历数组求最大 //不推荐,使用上面更简洁
二维数组新建:长度为n,并初始化每个数据为[]
(1)const arr= Array.from({ length: n }, () => []); //填充为0可以 ()=> new Array(len).fill(0)
(2)const arr= Array(n).fill([]);
(3)const arr= Array.from({ length: n }).map(() => []); //通常用于已有数组,但技术上可行
(4)const arr= [...Array(n)].map(() => []);
(5)const arr= new Array(n).fill(0).map(() => []); //不推荐,会创建额外的数组
(6)使用循环遍历:
const n = **; const array = []; for (let i = 0; i < n; i++) { array.push([]); }去掉数组每个元素的某个字段:
(1)不改变原数组:const newArr = arr.map(item =>{const{id, ...res}= obj; return res})
(2)改变原数组:arr.forEach(item => {deleteitem?.id })
删除数组指定元素:
(1)知道要删的元素用filter:arr = arr.filter(item => item?.id !== ***)
(2)知道要删的元素索引用splice:arr.splice(index, 1) -→或者findIndex找索引,≠-1就取
复制数组:
(1)copeArr = arr.slice();
(2)copeArr = [...arr];
(3)copeArr = Array.from(arr);
(4)copeArr = arr.concat();
(5)map、forEach、for循环遍历
数组去重、判重、判同、获取重复:
(1)set:
let deduplicateSet = new Set(arr?.map(item=>item?.id); // 数组去重
if(deduplicateSet?.size !== arr?.length) //true则存在重复元素
(2)some/every、filter:
if(arr?.some(item=> item?.id !== currentId)) //true则存在不同
if(arr?.every(item=> item?.id === currentId)) //false则存在不同
let newArr = arr?.filter(item=>item?.id !== currentId) //newArr的length>0则存在不同
(3)map:
let countMap = new Map();
arr.forEach(item=>{
if(countMap.has(item)) return true; // 存在重复
else countMap.set(item, 1);
})
return false //无重复
(4)获取重复元素数组:
// 1、map let countMap = new Map(); let duplicateList = []; arr.forEach((item, index)=>{ if(countMap.has(item?.id)) { duplicateList.push(index+1); //存重复的所有元素行序 }; else countMap.set(item?.id, true); }) // 2、set let countSet = new Set(); let duplicateList = []; arr.forEach((item, index)=>{ if(countSet.has(item?.id)) { duplicateList.push(index+1); //存重复的所有元素行序 }; else countSet.add(item?.id); })
集合 Set
let nst = new Set() //创建一个空的Set集合——可包含初始值Set(['x', 'y'])
nst.add('z') //向Set集合中添加新的元素——若该元素已经存在, 则不会重复添加,因为 Set 中的元素必须唯一
nst.delete('z') //从Set集合中删除元素console.log("nst.has",nst.has('y')) //检查Set集合是否包含指定元素
console.log("nst.size", nst.size) //获取Set集合的大小
arr = Array.from(nst) //使用 Array.from()方法将 Set集合 转换为 数组
arr = [...nst] //使用扩展运算符将 Set集合 转换为 数组
for(letitem ofnst) //使用for...of循环遍历 Set集合
nst.forEach(value=> { }) //使用forEach方法来遍历 Set集合
nst.clear() //清空 SetnumSet = new Set(numArr) //数组去重,将 数组 转换为 Set集合
字典 Map
基本用法:
let person = new Map ([ //创建Map集合
["name", "ABC"],
["gender", "女"],
])let map = new Map();
map.set(key, value); //向map中添加键值对,map中每个键唯一,当使用相同的键再次调用 set() 方法时, 会替换原来键对应的值
value = map.get(key); //输出key对应的value,若键不存在,返回undefined
flag = map.has(key) //map中是否存在指定的键,返回true/false
flag = map.delete(key) //删除指定键值对,删除成功返回true
map.clear() //清空Map所有键值对
nums = map.size // 返回map中键值对数量
转换与迭代:
arr = Array.from(person) //将Map集合转换为数组
arr = [...person] //使用扩展运算符将 Map集合 转换为 数组for(let key of map.keys()) // 返回所有键的迭代
for(let value of map.values()) // 返回所有值的迭代
for(let entry of map.entries()) // 返回所有键值对的迭代器,entry是[key, value]
for(let[key, value] ofperson) //使用for...of循环遍历Map集合——[key, value] 就是一种解构语法, 用于将 Map 集合中的键值对解构为 key 和 value 两个变量
person.forEach((value, key)=> { }) //使用forEach方法遍历Map集合的键值对obj =Object.fromEntries(person) //字典转对象,是Object.entries()的反函数
对象 Object
let person = { //创建对象
name: "ABC",
gender: "女"}
person.gender = "男" //与map一样,每个键都是唯一的,使用相同的键再次赋值
deleteperson.gender //删除属性has = "gender"inperson //检查对象是否包含指定属性
Object.keys(person) //用于获取对象属性名的数组
console.log("length", Object.keys(person).length) //获取对象的属性数量Object.entries(person) //用于获取对象的键值对数组
for(letkey inperson) { } //for...in 用于遍历对象的可枚举属性
Object.entries(person).forEach(([key, value])=> {}) //使用forEach方法遍历对象属性和值person = {} //清空对象
{ name: userName, gender } = person //解构+重命名
{ gender = "女" } = person //解构+新建设置默认值比较两个键值对的键,找出A有B没有的键放入数组:
(1)for...in+hasOwnProperty
:let onlyInA = []; //存A有B没有的键 for (let key in A) { if (A.hasOwnProperty(key) && !B.hasOwnProperty(key)) { onlyInA.push(key); } }(2)Object.keys和filter
:Object.keys(A).filter(key => !B.hasOwnProperty(key));
字符串 String
str.length // 字符串长度
str.toLowerCase() // 转小写str.toUpperCase() // 转大写
str[2] // 返回字符串在索引处的的字符
str = [...web] // 字符串转为字符数组
num =parseInt("168") // 字符串转 int
str2 = str1.replace("x", "y") // 字符串替换
str2 = str1.replaceAll("x", "y") // 字符串替换——在字符串中查找匹配的子串,并替换与正则表达式匹配的所有子串。str = " com ".trim() // 去除字符串两侧指定的字符
//去单边的空格trimStart()/trimLeft()、trimEnd()/trimRight
str.includes("xyz") // 判断是否包含某个字符串——boolean
loc = str.indexOf("xxx") // 返回字符串中第一次出现某个字符串的位置,若不存在则返回-1
result = str.startsWith("http") // 判断一个字符串是否以指定的前缀开头
result = str.endsWith("com") // 判断一个字符串是否以指定的后缀结尾
arr = "x,y,z".split(",") // 将字符串按照指定字符分割成数组
subStr1 = str.substr(0, 7) // 字符串截取 substr(开始位置,截取长度)
let subStr2 = str.substr(-3) //后三位
let subStr3 = str.substr(3) //[字符串下标从0开始]从第4个位置开始截取到末尾
repeatstr = str.repeat(3) //重复字符串——重复3次字符串
str= "xyz".padStart(7, "-") //在字符串前添加指定数量的填充字符(默认空格填充), 直到该字符串达到指定的长度——由于 xyz占 3 个字符, 因此只需要再添加 4 个横线, 即可达到总长度7
str= "xyz".padEnd(7, "-") //在字符串后添加指定数量填充字符, 直到该字符串达到指定的长度字符串的遍历:
for(let charofstr)
for(let i=0; i<str?.length; i++) →str[i]或者str.charAt(i)
str.split('').forEach(char=>{}) //通过转换为数组,再遍历
Array.from(str).forEach(char =>{})
[...str].forEach(char =>{})
字符串去掉指定字符:
(1)使用正则+replace:var regex=new RegExp(char,'g'); str.replace(regex,'');
(2)使用split+join:str?.split(char)?.join('')
(3)使用indexOf+splice:找到下标,判断≠-1就用splice去除
(4)使用模板字符串和正则:str?.replace(new RegExp(`${char}`,'g'),'');
(5)用slice截取字符串拿到子串(不改变原字符串):str.slice(1)表示去除第一个字符