增删
增加
unshift 前增
let arr = [1];
arr.unshift(2); // [2,1]
push 后增
let arr = [1];
// 可以一次push多个值
arr.push(2); // [1,2]
删除
shift 前删
let arr = [1,2,3];
arr.shift(); // 1
console.log(arr); // [2,3]
pop 后删
let arr = [1,2,3];
arr.pop(); // 3
console.log(arr); // [1,2]
splice 替换
splice方法可以用来对js的数组进行删除,添加,替换等操作。主要看第二个参数是什么,如果是0表示增加,如果是大于0的表示删除,如果有第三个参数表示添加或者替换。
- 删除功能,第一个参数为第一项位置,第二个参数为要删除几个。用法:array.splice(index,num),返回值为删除内容,array为结果值。
2. 插入功能,第一个参数(插入位置),第二个参数(0),第三个参数(插入的项)。 用法:array.splice(index,0,insertValue),返回值为空数组,array值为最终结果值。
3. 替换功能,第一个参数(起始位置),第二个参数(删除的项数),第三个参数(插入任意数量的项)。 用法:array.splice(index,num,insertValue),返回值为删除内容,array为结果值。
拼接
push
let arr1 = [1, 2]
let arr2 = [3, 4]
arr1.push(arr2)
console.log(arr1) // [1,2,[3,4]]
concat: 返回拼接后的副本,不会改变原数组
let arr1 = [1, 2]
let arr2 = [3, 4]
let arr3 = arr1.concat(arr2)
console.log(arr3) // [1,2,3,4]
查找与过滤
indexOf/lastIndexOf
let arr = [1, 2, 3, 1, 5]
let index = arr.indexOf(1)
console.log(index) // 0
let arr = [1, 2, 3, 2, 1, 2]
let index = arr.lastIndexOf(1)
console.log(index) // 4
返回元素在数组中首次出现的下标,如果找不到,返回 -1
find/findIndex
find()方法用于查找数组中符合条件的第一个元素,如果没有符合条件的元素,则返回undefined。findIndex()则是返回元素的下标。
如果找到第一个元素,就结束查找。
let arr = [1, 2, 3, 4, 5]
let num = arr.find(item => item > 1)
console.log(num) // 2
includes
判断数组中是否存在该元素,参数:查找的值、起始位置,可以替换 ES5 时代的 indexOf 判断方式。
var a = [1, 2, 3];
a.includes(2); // true
a.includes(4); // false
filter
对数组的每一项都运行给定的函数,返回 结果为 ture 的项组成的数组
var words = ["spray", "limit", "elite", "exuberant", "destruction", "present", "happy"];
var longWords = words.filter(function(word){
return word.length > 6;
});
// ["exuberant", "destruction", "present"]
some/every
- some: 对数组的每一项都运行给定的函数,任意一项都返回 ture,则返回 true
- every: 对数组的每一项都运行给定的函数,每一项都返回 ture,则返回 true
// every
function isBigEnough(element, index, array) {
return element < 10;
}
[2, 5, 8, 3, 4].every(isBigEnough); // true
// some
function compare(element, index, array) {
return element > 10;
}
[2, 5, 8, 1, 4].some(compare); // false
[12, 5, 8, 1, 4].some(compare); // true
ES6新增常用方法
Array.from
将类似数组的对象(array-like object)和可遍历(iterable)的对象转为真正的数组。
const bar = ["a", "b", "c"];
Array.from(bar); // ["a", "b", "c"]
Array.from('foo'); // ["f", "o", "o"]
Array.of
用于将一组值,转换为数组。这个方法的主要目的,是弥补数组构造函数 Array() 的不足。因为参数个数的不同,会导致 Array() 的行为有差异。
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
entries()、values()、 keys()
const arr = ['a', 'b', 'c'];
for(let v of arr.entries()) {
console.log(v)
}
// [0, 'a'] [1, 'b'] [2, 'c']
const arr = ['a', 'b', 'c'];
for(let v of arr.values()) {
console.log(v)
}
//'a' 'b' 'c'
const arr = ['a', 'b', 'c'];
for(let v of arr.keys()) {
console.log(v)
}
// 0 1 2
sort排序
sort方法可直接调用,不传入任何参数,也可传入一个比较函数作为参数。
不传参数的情况
此方法不传入参数时,会使用默认排序方式。先调用每个元素的toString() 方法,然后按照转换后字符串的 Unicode 编码来进行排序,如:我们可以看到结果不是按顺序大小排列的
[1, 2, 3, 15, 22, 33].sort() // 1, 15, 2, 22, 3, 33
传入函数参数(参数只能是函数)
传入函数参数,可以让调用者按照自己的意愿对元素进行排序。
// 函数参数的实现
function compare(value1, value2) {
if (value1 < value2) {
return 1
}
if (value1 > value2) {
return -1
}
return 0
}
- 如果函数返回 1 排序后 value1 会位于 value2 之后
- 返回 -1 排序后 value1 会在 value2 之前;
- 返回 0 则说明两个元素相等,排序后位置不会发生变化。
注意:传入的参数函数必须要返回值,像这么写是不行的:
function compare(value1, value2) {
if (value1 < value2) {
return 1
}
}
// 修改为:
function compare(value1, value2) {
if (value1 < value2) {
return 1
}
return -1
}
若 value1 和 value2 的比较结果是随机的,会出现数组乱序的现象。可以利用这一特性来打乱一个数组。
调用 sort 方法,在排序过程中,每次执行会取得随机浮点数。根据随机数来调整每个元素的位置。最后得到乱序之后的数组。
arr.sort(function(a,b){
return Math.random()>.5 ? -1 : 1;
});
转换
toString
let arr = [1, 2]
let str = arr.toString()
console.log(str) // "1,2"
join
let arr = [1, 2, 3]
let str1 = arr.join('.')
console.log(str1) //"1.2.3"
let str2 = arr.join('$')
console.log(str2) //"1$2$3"
map
返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
var users = [
{name: "张含韵", "email": "zhang@email.com"},
{name: "江一燕", "email": "jiang@email.com"},
{name: "李小璐", "email": "li@email.com"}
];
var emails = users.map(function (user) { return user.email; });
//["zhang@email.com", "jiang@email.com", "li@email.com"]
reduce
arr.reduce(function(prev, cur, index){
...
}, init);
var arr = [3,9,4,3,6,0,9];
var sum = arr.reduce(function (prev, cur) {
return prev + cur;
},0);
- prev 表示上一次调用回调时的返回值,或者初始值 init;
- cur 表示当前正在处理的数组元素;
- index 表示当前正在处理的数组元素的索引,若提供 init 值,则索引为0,否则索引为1;
- init 表示初始值,如果没传,那么就是数组的第一项。
求数组项最大值,求和
var max = arr.reduce(function(prev, cur) {
return Math.max(prev, cur)
})
数组去重
var newArr = arr.reduce(function(prev, cur) {
prev.indexOf(cur) === -1 && prev.push(cur)
return prev
}, [])
let arr = [1, 2, 3, 4, 4, 1]
let newArr = arr.reduce((pre, cur) => {
if (!pre.includes(cur)) {
return pre.concat(cur)
} else {
return pre
}
}, [])
console.log(newArr) // [1, 2, 3, 4]
计算数组中每个元素出现的次数
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']
let nameNum = names.reduce((pre, cur) => {
if (cur in pre) {
pre[cur]++
} else {
pre[cur] = 1
}
return pre
}, {})
console.log(nameNum) //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
将二维数组转化为一维
let arr = [
[0, 1],
[2, 3],
[4, 5]
]
let newArr = arr.reduce((pre, cur) => {
return pre.concat(cur)
}, [])
console.log(newArr) // [0, 1, 2, 3, 4, 5]
用递归进行多维数组的打平,递归有个特点就是要有个返回值:
let arr = [
[0, 1],
[2, 3],
[4, [5, 6, 7]]
]
const newArr = function(arr) {
return arr.reduce(
(pre, cur) => pre.concat(Array.isArray(cur) ? newArr(cur) : cur),
[]
)
}
console.log(newArr(arr)) //[0, 1, 2, 3, 4, 5, 6, 7]
将数组打平,ES6有个新的方法flat:
[1, 2, [3, 4]].flat() // [1, 2, 3, 4]
数组的优劣和操作的时间复杂度
优点:更新查找快,由于数组是线性查存储,所以我们只需要给到我们想要的元素下标,就可以方便的更新元素和查找元素。
缺点:增删慢,还是因为数组的线性存储,举个比较简单的例子,比如说我们的书桌上堆放着一摞书,我想要拿第 5 本,我需要动前 4 本才可以拿到想要的。如果书我想把一本书放在中间位置,同样需要动中间位置之前的所有书才可以。
时间复杂度:由于更新查找的时候只需要提供下标,所以时间复杂度是O(1)。增加和删除的时候需要改动数组中的其他元素,所以时间复杂度是O(n)。