写一篇关于 js 数组相关操作的总结,方便后续查阅。
数组是一种类列表对象,它的原型中提供了遍历和修改元素的相关操作。JavaScript 数组的长度和元素类型都是非固定的。因为数组的长度可随时改变,并且其数据在内存中也可以不连续,所以 JavaScript 数组不一定是密集型的,这取决于它的使用方式。更多可以在MDN上查阅。
参考自各位大佬:
数组的基本操作
创建数组
const fruits = ["Apple", "Banana"];
console.log(fruits.length); // 2新增元素
push 新增元素到数组的末尾
const fruits = ["Apple", "Banana"];
fruits.push("Orange");
console.log(fruits); // ['Apple', 'Banana', 'Orange']unshift 新增元素到数组的头部
const fruits = ["Apple", "Banana"];
fruits.unshift("Mango");
console.log(fruits); // ['Mango', 'Apple', 'Banana']查询元素
通过索引访问数组元素
const fruits = ["Apple", "Banana"];
let apple = fruits[0];
console.log(apple); // Apple找出某个元素在数组中的索引
const fruits = ["Apple", "Banana"];
fruits.push("Mango"); // ['Apple', 'Banana', 'Mango']["Apple", "Banana", "Mango"]
let pos = fruits.indexOf("Banana");
console.log(pos); // 1修改元素
const fruits = ["Apple", "Banana", "Mango"];
fruits[0] = "Orange";
console.log(fruits); // ['Orange', 'Banana', 'Mango']删除元素
pop 删除数组末尾的元素
const fruits = ["Apple", "Banana", "Mango"];
fruits.pop();
console.log(fruits); // ['Apple', 'Banana']shift 删除数组头部元素
const fruits = ["Apple", "Banana", "Mango"];
fruits.shift();
console.log(fruits); // ['Banana', 'Mango']
数组遍历
js 数组的索引是从 0 开始的,第一个元素的索引为 0,最后一个元素的索引等于该数组的 长度 length 减 1。如果指定的索引是一个无效值,js 数组并不会报错,而是会返回 undefined。
for 循环
它用途广泛,但是当我们要遍历数组时也很麻烦。
如果我们不想从第一个数组元素开始循环时它仍然很有用,用其他的循环机制很难做到这一点。
const array = [0, 1, 2, 3, 4, 5, 6];
for (let i = 0; i < array.length; i++) {
console.log(i);
}
for-in 循环
对象也可以用此进行遍历 key
for-in 访问继承属性的实际用途是:遍历对象的所有可枚举属性。
for-in 不是循环遍历数组的好方法:
它访问的是属性键,而不是值。
作为属性键,数组元素的索引是字符串,而不是数字。
它访问的是所有可枚举的属性键(自己的和继承的),而不仅仅是 Array 元素的那些。
const array = [0, 1, 2, 3, 4, 5, 6];
for (const key in array) {
console.log(key);
}
forEach 循环
缺点:
不能在它的循环体中使用 await。
不能提前退出 forEach() 循环。而在 for 循环中可以使用 break。
const array = [0, 1, 2, 3, 4, 5, 6];
array.forEach((item, index) => {
console.log(item, index);
});
for-of 循环
for-of 在循环遍历数组时非常有效:
用来遍历数组元素。
可以使用 await
- 如果有需要,可以轻松地迁移到 for-await-of。
甚至可以将 break 和 continue 用于外部作用域。
const array = [0, 1, 2, 3, 4, 5, 6];
for (const item of array) {
console.log(item);
}
数组去重
数组去重一般都是两个数组之间进行比较去重的。
双重 for 循环
将两个数组合为一个数组,然后双重 for 循环,在外层遍历所有元素,内层进行检查元素是否重复。 这种双重循环判断的去重的效率是极差的
function distinct(arr1, arr2) {
let arr = arr1.concat(arr2);
const len = arr.length;
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j++) {
if (arr[i] == arr[j]) {
arr.splice(j, 1);
len--;
j--;
}
}
}
return arr;
}
Array.filter + indexOf
将两个数组拼接为一个数组,然后使用 ES6 中的 Array.filter() 遍历数组,并结合 indexOf 来排除重复项
function distinct(arr1, arr2) {
let arr = arr1.concat(arr2);
return arr.filter((item, index) => {
return arr.indexOf(item) === index;
});
}
for...of + includes()
function distinct(arr1, arr2) {
let arr = arr1.concat(arr2);
let result = [];
for (let i of arr) {
!result.includes(i) && result.push(i);
}
return result;
}
Array.sort()
合并后数组进行排序,再比较相邻元素去重,效率会比前面三个高。
function distinct(arr1, arr2) {
let arr = arr1.concat(arr2);
arr = arr.sort();
const len = arr.length;
let result = [arr[0]];
for (let i = 1; i < len; i++) {
arr[i] !== arr[i - 1] && result.push(arr[i]);
}
return result;
}
new Set()
使用 ES6 新增的 new Set() 方法来判断去重。这种方式比较推荐。
function distinct(arr1, arr2) {
return Array.from(new Set([...arr1, ...arr2]));
}
for...of + Object
首先创建一个空对象,然后用 for 循环遍历。利用对象的属性不会重复这一特性,校验数组元素是否重复。 这种效率是最高的。
function distinct(arr1, arr2) {
let arr = arr1.concat(arr2);
let arr = a.concat(b);
let result = [];
let obj = {};
for (let i of arr) {
if (!obj[i]) {
result.push(i);
obj[i] = 1;
}
}
return result;
}