最近在学习《数据结构与算法》,数据结构中数组的重要性不言而喻。 由于 js 随意的动态性,总结一下数组的用法。
Array
array 定义
- 通过 new Array 创建数组时, 如果是一个参数且必须是个正整数,就是在定义长度。若是多个参数,则是赋值。
1
var arr = new Array(5); //定义数组长度
ps: 在我看来,这是最不负责任的数组。
- Array如果通过索引赋值时,索引超过了范围,同样会引起
ƒ
大小的变化。
大多数其他编程语言不允许直接改变数组的大小(如:java),越界访问索引会报错。然而,JavaScript的Array
却不会有任何错误。在编写代码时,不建议直接修改Array
的大小,访问索引时要确保索引不会越界。1
2
3var arr = [1, 2, 3];
arr[5] = 'x';
arr; // arr变为[1, 2, 3, undefined, undefined, 'x']
同理,修改 arr.length 的值,一样改变数组长度。
改变原数组的方法 [push, pop, shift, unshift, sort, reverse, splice]
push 与 pop
与 数据 栈 stack 的 push、pop 方法概念相同,先进后出。
由于 length 随意更改,可得 push 的实现原理:1
2
3
4
5Array.prototype.myPush = function () {
for (let i = 0; i < arguments.length; i++) {
this[this.length] = arguments[i];
}
}unshift 和 shift
如果要往Array
的头部添加若干元素,使用unshift()
方法,shift()
方法则把Array
的第一个元素删掉:1
2
3
4
5
6
7Array.prototype.myUnShift = function () {
var newArr = []
for (let i = 0; i < arguments.length; i++) {
newArr[i] = arguments[i];
}
return newArr.concat(this);
}
要注意的是 arguments 是个类数组对象,无法直接使用 concat 方法。
- splice 切片
splice()
方法是修改Array
的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素:splice(开始切,截取长度,切口处加入新元素)
1
2
3
4
5
6
7
8
9
10var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
- sort
sort()
可以对当前Array
进行排序,它会直接修改当前Array
的元素位置,直接调用时,按照默认顺序排序:
但是 js 中 sort 与其他语言差距较大(如:java),排序是ascII 码 排序。1
2
3
4
5
6
7
8
9
10
11
12var arr = ['B', 'C', 'A'];
arr.sort();
arr; // ['A', 'B', 'C']
arr1 = [1,20,10,3];
arr1.sort()
arr1;// [1, 10, 20, 3]
// 比较 参数,return 正数 交换位置(即:a>b),return 负数 位置不变。
arr1.sort((a,b)=>{
return a-b;
})
//[1, 3, 10, 20]
所以,以后用 sort 一定传函数,以防不测。。。
sort 传入回调函数,可以实现乱序。1
2
3arr1.sort(() => {
return Math.random() - 0.5;
})
不改变原数组的方法 [ concat, join, split, toString, slice]
- concat
concat()
方法把当前的Array
和另一个Array
连接起来,并返回一个新的Array
:
1 | var arr = ['A', 'B', 'C']; |
注意,concat()
方法并没有修改当前Array
,而是返回了一个新的Array
。
实际上,concat()
方法可以接收任意个元素和Array
,并且自动把Array
拆开,然后全部添加到新的Array
里:1
2var arr = ['A', 'B', 'C'];
arr.concat(1, 2, [3, 4]); // ['A', 'B', 'C', 1, 2, 3, 4]
由于数组是典型的引用类型,数组赋值等操作时需要 concat。1
arr.push([].concat(temp))
- slice 截取
slice()
就是对应String的substring()
版本,它截取Array
的部分元素,然后返回一个新的Array
:
前开后闭1
2
3var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C']
arr.slice(3); // 从索引3开始到结束: ['D', 'E', 'F', 'G']
如果不给slice()
传递任何参数,它就会从头到尾截取所有元素。利用这一点,我们可以很容易地复制一个Array
:
1 | var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G']; |
第三个参数是 删除位置 将替换的内容1
arr.splice(0, 2, temp); //将 0 1替换 temp
- join
join()
方法是一个非常实用的方法,它把当前Array
的每个元素都用指定的字符串连接起来,然后返回连接后的字符串:
1 | var arr = ['A', 'B', 'C', 1, 2, 3]; |
如果Array
的元素不是字符串,将自动转换为字符串后再连接。
不传参数将自动以 ‘,’ 分隔。
注意 字符串中 split() 与 join 是可逆操作。
遍历方法
[].every(fun)
:返回一个boolean,判断每个元素是否符合func条件(所有都判断)(并没有改变原数组)
[].some()
:返回一个boolean,判断是否有元素是否符合func条件(有一个就行)(并没有改变原数组)
[].filter()
:返回一个符合func条件的元素数组(并没有改变原数组)
[].forEach(fun) 不生成新数组的迭代器方法,没有返回值, 改变原数组操作
[].map(fun)
有返回值,可以return出来,返回一个新的Array.
[].reduce(function(prev,cur,index,arr),init)