数组常用的方法有哪些
增:push、unshift、splice、concat
push
尾部插入unshift
前面插入splice
指定位置插入
splice方法特点:
- 修改原数组,js中修改原数组的方法不多,下文介绍
- 可以删除元素,splice(删除索引, 删除数量)
- 插入元素,splice(删除索引, 删除数量, '向后插入的元素')
- 如果删除数量为0,则表示不删除元素,同时如果填入元素则向后加入元素
concat
拼接数组
删:pop、shift、splice、slice
pop
在后面推出元素(结合push
相当于"栈",先进后出)shift
在前面推出元素(结合push
相当于"队列",先进先出)splice
指定删除数量即可删除元素slice
删除范围内的元素,返回删除的元素数组,不修改原数组,范围是左闭右开
TypeScript
const arr = [3, 1, 2];
const newArr = arr.slice(1, 2)
console.log(newArr, arr) // [ 1 ] [ 3, 1, 2 ]
改:splice、sort、reverse、fill
splice
修改数组
TypeScript
const arr = [3, 1, 2];
const newArr = arr.splice(1, 1, 'a')
console.log(newArr, arr) // [ 1 ] [ 3, 'a', 2 ]
sort
排序数组,修改原数组,并返回原数组的引用,不是拷贝
TypeScript
const arr = [3, 1, 2];
const increaseArr = arr.sort((a, b) => {
return a - b;
});
const decreaseArr = arr.sort((a, b) => {
return b - a;
});
reverse
反转数组,修改原数组,返回原数组的引用,不是拷贝
TypeScript
const arr = [3, 1, 2];
const reverseArr = arr.reverse();
console.log(arr, reverseArr === arr); // [ 2, 1, 3 ] true
fill
用指定值填充数组的指定范围,返回修改后的数组(引用),范围是左开右闭
TypeScript
const arr = [1, 2, 3, 4];
arr.fill(5, 1,3 )
console.log(arr); // [ 1, 5, 5, 4 ]
查:inculdes、indexOf、find、findIndex、lastIndexOf
includes
数组中是否包含元素,是则返回true,第二个参数指定查找的起始位置
TypeScript
const arr = [3, 1, 2];
console.log(arr.includes(3, 1));
console.log(arr.includes(3, 0));
// false;
// true;
indexOf
返回元素的索引,找不到则返回-1,也有第二个参数指定位置
TypeScript
const arr = [3, 1, 2];
console.log(arr.indexOf(3, 1));
console.log(arr.indexOf(3, 0));
// -1;
// 0;
find
查找指定元素,返回这个元素,通过函数指定查找规则
TypeScript
const arr = [
{
a: 3,
b: 4
},
{
a: 1,
b: 5
}
];
console.log(
arr.find((val, idx) => {
return val.a > 2
})
);
// { a: 3, b: 4 }
findIndex
TypeScript
const arr = [
{
a: 3,
b: 4
},
{
a: 1,
b: 5
}
];
console.log(
arr.findIndex((val, idx) => {
return val.a > 2
})
);
// 0
lastIndexOf
倒查元素索引,注意第二个参数索引是正排的
TypeScript
const arr = [3, 1, 2];
console.log(arr.lastIndexOf(2, 0)); // -1
console.log(arr.lastIndexOf(2, 2)); // 2
迭代数组:forEach、map、every、some、reduce、filter
forEach
遍历数组,return无法终止forEach的循环,但是可以使用throw一个报错,终止循环
TypeScript
const arr = [3, 1, 2];
const newArr = arr.forEach((val, idx, arr) => {
console.log(val + 1);
// 4;
// 2;
// 3;
});
const arr = [1, 2, 3, 4];
// 使用return 无法终止循环
arr.forEach((val, idx, arr) => {
if (val === 3) {
return;
}
console.log(val);
// 1;
// 2;
// 4;
});
// 可以使用throw + try catch
arr.forEach((val, idx, arr) => {
try {
if (val === 3) {
throw new Error();
}
console.log(val);
} catch (err) {}
});
map
遍历数组,可以修改数组,返回一个新的数组
TypeScript
const arr = [3, 1, 2];
const newArr = arr.map((val, idx, arr) => {
return val + 1
})
console.log(newArr, arr) // [ 4, 2, 3 ] [ 3, 1, 2 ]
every
判断数组的每一个元素是否都满足规则
TypeScript
const arr = [3, 1, 2];
const res1 = arr.every((val) => {
return val > 0
})
const res2 = arr.every((val) => {
return val > 1;
});
console.log(res1) // true
console.log(res2) // false
some
判断数组中是否有元素满足规则
TypeScript
const arr = [3, 1, 2];
const res1 = arr.some((val, idx, arr) => {
return val > 2;
});
const res2 = arr.some((val, idx, arr) => {
return val > 3;
});
console.log(res1, res2); // true false
reduce
遍历数组并返回数组求和结果
TypeScript
const arr = [3, 1, 2];
const res = arr.reduce((pre, cur, curIdx, arr) => {
return pre + cur;
}, 0);
console.log(res) // 6
filter
过滤符合规则的元素,返回新数组
TypeScript
const arr = [3, 1, 2];
const newArr = arr.filter((val, idx, arr) => {
return val > 1;
});
console.log(newArr, arr) // [ 3, 2 ] [ 3, 1, 2 ]
修改原数组的方法
push
pop
unshift
shift
splice
reverse
sort
fill
一共八个方法
手写常用数组方法
map
TypeScript
const arr = [1, 2, 3, 4];
Array.prototype.myMap = function (callback) {
const res = [];
for (let i = 0; i < this.length; i++) {
res.push(callback(this[i], i, this));
}
return res;
};
console.log(
arr.myMap((val, idx, arr) => val + 1),
arr
);
// [ 2, 3, 4, 5 ] [ 1, 2, 3, 4 ]
filter
TypeScript
const arr = [3, 1, 2, 4];
Array.prototype.myFilter = function (callback) {
const res = [];
for (let i = 0; i < this.length; i++) {
const a = callback(this[i], i, this);
if (!a) continue
res.push(this[i]);
}
return res;
};
console.log(
arr.myFilter((val, idx, arr) => val > 2),
arr
);
// [ 3, 4 ] [ 3, 1, 2, 4 ]
every
TypeScript
const arr = [3, 1, 2, 4];
Array.prototype.myEvery = function (callback) {
for (let i = 0; i < this.length; i++) {
if (!callback(this[i], i, this)) {
return false;
}
}
return true;
};
console.log(
arr.myEvery((val, idx, arr) => val > 0),
arr
); // true
console.log(
arr.myEvery((val, idx, arr) => val > 1),
arr
); // false
reduce
TypeScript
const arr = [3, 1, 2, 4];
Array.prototype.myReduce = function (callback, initValue) {
let pre = initValue ? initValue : 0;
let sum = 0;
for (let i = 0; i < this.length; i++) {
let cur = this[i];
pre = callback(pre, cur, i, this);
}
return pre;
};
console.log(
arr.myReduce((pre, cur, arr) => pre + cur),
arr
); // 10 [ 3, 1, 2, 4 ]
数组扁平化-手写扁平数组
如何将数组扁平化
- 使用数组内置方法
flat
TypeScript
const arr = [1, [2, [3, [4]]]];
console.log(arr.flat(Infinity), arr); // [ 1, 2, 3, 4 ] [ 1, [ 2, [ 3, [Array] ] ] ]
- 手写扁平数组方法,递归数组,核心是判断是否是数组,是数组则递归数组,并通过depth控制深度
TypeScript
Array.prototype.flatten = function (depth) {
let res = [];
function f(depth) {
for (let i = 0; i < this.length; i++) {
if (Array.isArray(this[i]) && depth > 0) {
f.call(this[i], depth - 1);
} else {
res.push(this[i]);
}
}
}
f.call(this, depth);
return res;
};
console.log(arr.flatten(3)); // [ 1, 2, 3, 4 ]
- 使用reduce,递归遍历数组
TypeScript
Array.prototype.flatten = function () {
return this.reduce((pre, cur) => {
if (Array.isArray(cur)) {
pre.push(...cur.flatten());
} else {
pre.push(cur);
}
return pre
}, []);
};
console.log(arr.flatten()); // [ 1, 2, 3, 4 ]
while
每次判断数组是否包括数组,如果有则使用...
解构数组
TypeScript
Array.prototype.flatten = function() {
let result = [...this]
// 如果数组上有子数组,则解构数组
while (result.some((val) => Array.isArray(val))) {
result = [].concat(...result)
}
return result
}
console.log(arr.flatten()); // [ 1, 2, 3, 4 ]
- 使用字符串转扁平数组,前提是数组都是一样的元素
TypeScript
Array.prototype.flatten = function () {
return this.toString()
.split(",")
.map((item) => +item);
};
console.log(arr.flatten()); // [ 1, 2, 3, 4 ]
字符串常用方法有哪些
增:concat
concat
拼接一个字符串到原字符串,不修改原字符串,返回新字符串
TypeScript
const str = "hello"
const newStr = str.concat(' world')
console.log(newStr, str); // hello world hello
删:slice、substring
slice
指定切割位置,返回切割的字符串
TypeScript
const str = "hello";
const newStr = str.slice(1, 2);
console.log(newStr, str); // e hello
substring
和slice
效果一致,只有语义的区别,因为slice
原本为数组上的方法
TypeScript
const str = "hello";
const newStr = str.substring(1,2)
console.log(newStr, str); // e hello
改:replace、repeat、toLowerCase、toUpperCase、trim、padEnd、split
replace
替换字符,一般配合正则使用,replaceAll
会替换字符串中所有符合的字符,或者使用正则/g
也是一样的效果
TypeScript
const str = "hello";
const newStr = str.replace('o', 'n')
console.log(newStr, str); // helln hello
repeat
重复字符串
TypeScript
const str = "hello";
const newStr = str.repeat(2)
console.log(newStr, str); // hellohello hello
toLowerCase
将字符串转为小写
TypeScript
const str = "Hello World";
const newStr = str.toLowerCase()
console.log(newStr, str); // hello world Hello World
toUpperCase
将字符串转为大写
TypeScript
const str = "Hello World";
const newStr = str.toUpperCase()
console.log(newStr, str); // HELLO WORLD Hello World
trim
去除字符串两边空白字符
TypeScript
const str = " Hello ";
const newStr = str.trim()
console.log(newStr);
console.log(str);
// Hello
// Hello
padEnd
向后补充字符串,padStart
向前补充字符串,第一个参数是补充后的字符串长度,第二个参数是用什么字符串补
TypeScript
const str = "a";
const str1 = str.padStart(10, 'abcdefghijk'); // 补充的字符串比10长
const str2 = str.padEnd(10, 'abcdefghijk'); // 补充的字符串比10长
console.log(str1); // abcdefghia
console.log(str2); // aabcdefghi
const str3 = str.padStart(10, 'b')
const str4 = str.padEnd(10, 'b')
console.log(str3); // bbbbbbbbba
console.log(str4); // abbbbbbbbb
const str5 = str.padStart(10, 'bc')
const str6 = str.padEnd(10, 'bc')
console.log(str5); // bcbcbcbcba
console.log(str6); // abcbcbcbcb
使用padEnd
和padStart
可以用来计算大数字相加,这个字节经常考
TypeScript
let a = 341314313134141251;
let b = 1241241241;
function add(n, m) {
n = n.toString();
m = m.toString();
let len = Math.max(n.length, m.length);
n = n.padStart(len, "0");
m = m.padStart(len, "0");
let res = "";
let carry = 0;
for (let i = len - 1; i >= 0; i--) {
const x = Number(n[i]);
const y = Number(m[i]);
const v = x + y + carry;
res = v % 10 + res;
carry = Math.floor(v / 10);
}
if (carry > 0) {
res = carry + res;
}
return +res;
}
console.log(add(a, b)); // 341314314375382460
console.log(a + b); // 341314314375382460
split
将字符串以某个字符串作为分隔符,转为数组
TypeScript
const str = 'a,b,e,d'
const arr = str.split(',')
console.log(str, arr); // a,b,e,d [ 'a', 'b', 'e', 'd' ]
查:charCodeAt、endsWith、match
charCodeAt
和charAt
、at
不同,他返回字符的assci码,在一些需要使用字典序的代码中,可以使用 **charCodeAt
**方法
TypeScript
const str = 'image.png'
console.log(str.charCodeAt(0)); // 105
endsWith
以什么结尾,比如判断文件名后缀以什么结尾,同时还有以什么开头startsWit
TypeScript
const str = 'image.png'
console.log(str.endsWith('.png')); // true
match
一般填入一个正则,用于匹配字符串,并返回匹配的字符串位置信息
TypeScript
const str = 'image.png'
console.log(str.match('.png')); // [ '.png', index: 5, input: 'image.png', groups: undefined ]