数组
按次序排列的一组值,用方括号表示。可以在定义时赋值,也可以先定义后赋值。
声明
- let arr = new Array();
如果使用单个参数(即数字)调用 new Array,那么它会创建一个指定了长度,却没有任何项的数组。
- let arr = []; 推荐
数组可以存储任何类型的元素。
// 混合值
let arr = [ 'Apple', { name: 'John' },{age:15}, true, function() { alert('hello'); } ];
// 获取索引为 1 的对象然后显示它的 name
alert( arr[1].name ); // John
方法
pop/push, shift/unshift 方法
sort:数组的排序,返回排序后的数组,但是返回值通常会被忽略,因为修改了 arr 本身
reverse:将数组颠倒,返回颠倒后的数组
concat(...items) —— 返回一个新数组:复制当前数组的所有元素,并向其中添加 items。如果 items 中的任意一项是一个数组,那么就取其元素。
join:数组的连接
indexOf:第一次出现的索引位置
lastIndexOf:最后一次出现的索引位置
indexOf/lastIndexOf 和 includes arr.indexOf、arr.lastIndexOf 和 arr.includes 方法与字符串操作具有相同的语法,并且作用基本上也与字符串的方法相同,只不过这里是对数组元素而不是字符进行操作:
arr.indexOf(item, from) 从索引 from 开始搜索 item,如果找到则返回索引,否则返回 -1。 arr.lastIndexOf(item, from) —— 和上面相同,只是从右向左搜索。 arr.includes(item, from) —— 从索引 from 开始搜索 item,如果找到返回布尔值 true(否则false)。
includes 的一个非常小的差别是它能正确处理NaN,而不像 indexOf/lastIndexOf:
const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1(应该为 0,但是严格相等 === equality 对 NaN 无效)
alert( arr.includes(NaN) );// true(这个结果是对的)
map:数组的遍历和映射 它遍历数组的每个元素,并返回结果数组。 forEach:遍历数组 toString:转字符串 把数组转换为字符串,并返回结果。
slice :数组的截取复制,返回复制的新数组 slice(m,n): 从数组索引m开始,截取到索引n,但是不包含n;[前包后不包]
slice():数组的克隆 slice(0); 原有数组不发生改变;
slice将伪数组转化为数组: var arr = Array.prototype.slice.call(arrayLike);
splice:删除数组中的某几项,返回值是被删除的元素,会改变原数组
splice(m,n): 从索引开始,删除n个
splice(m) : 从索引m开始删除到末尾;
splice(m,x,n);替换从索引m开始,删除x个,用n替换
Array.from()
ES6为Array增加了from函数用来将其他对象转换成数组。返回值:一个新的数组
当然,其他对象也是有要求,也不是所有的,可以将两种对象转换成数组。
1.部署了Iterator接口的对象,比如:Set,Map,Array。
2.类数组对象,就是一个对象必须有length属性,没有length,转出来的就是空数组。
onsole.log(Array.from('foo'));
// expected output: Array ["f", "o", "o"]
console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]
reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
arr.reduce(function(prev,cur,index,arr){
...
}, init);
其中,
arr 表示原数组;
prev 表示上一次调用回调时的返回值,或者初始值 init;
cur 表示当前正在处理的数组元素;
index 表示当前正在处理的数组元素的索引,若提供 init 值,则索引为0,否则索引为1;
init 表示初始值。
find 和 findIndex
find返回找到的第一个元素的值,find方法不会改变数组。
let result = arr.find(function(item, index, array) {
// true,返回 item 并停止迭代
// 否则返回 undefined
});
比如要找到ID为1的用户
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
let user = users.find(item => item.id == 1);
alert(user.name); // John
例子中传给 find 一个单参数函数 item => item.id == 1。这很典型,并且 find 方法的其他参数很少使用。
arr.findIndex 方法(与 arr.find 方法)基本上是一样的,但它返回找到元素的索引,而不是元素本身。并且在未找到任何内容时返回 -1
filter 返回的是所有匹配元素组成的数组,没找到返回空数组
遍历
- for 循环:
let arr = ["Apple", "Orange", "Pear"];
for (let i = 0; i < arr.length; i++) { alert( arr[i] ); }
- for..of:
let fruits = ["Apple", "Orange", "Plum"];
// 遍历数组元素 for (let fruit of fruits) { alert( fruit ); }
for..of 不能获取当前元素的索引,只是获取元素值,
- arr.forEach 遍历数组 该函数的结果(如果它有返回)会被抛弃和忽略
比如
// 对每个元素调用 alert
["Bilbo", "Gandalf", "Nazgul"].forEach(alert);
- for in 数组也是对象,所以使用 for..in 也是可以的:但不推荐使用
let arr = ["Apple", "Orange", "Pear"];
for (let key in arr) { alert( arr[key] ); // Apple, Orange, Pear }
for..in 循环会遍历 所有属性,不仅仅是这些数字属性。
for..in 循环适用于普通对象,通常来说,我们不应该用 for..in 来处理数组。
for…in..和for…of..的区别?
for in 遍历循环对象
同时for in也可以遍历数组,但是会出现以下问题 1、index索引为字符串型数字,不能直接进行几何运算 2、遍历顺序有可能不是按照实际数组的内部顺序 3、使用for in会遍历数组所有的可枚举属性,包括原型。 for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值。 for of 遍历循环数组内的元素,而不包括数组的原型属性method和索引name
数组拍平
数组扁平化:将一个多维数组变为一维数组
[1, [2, 3, [4, 5]]] ------> [1, 2, 3, 4, 5]
- reduce
var arr=[1,[2,3,[4,5]]];
function flatten(arr){
return arr.reduce(function(pre,cur){
if(!Array.isArray(cur)){
return [...pre,cur];
}else{
return [...pre,...flatten(cur)]
}
},[])
}
console.log(flatten(arr))
- 递归
var arr=[1,[2,3,[4,5]]];
function product() {
// 1、创建一个空数组,
var newarr = [];
///2、并且返回一个函数,函数参数为要拍平的数组
return function flatten(arr) {
// 3、循环数组,判断每一项,不为输的话将其塞入newarr
// 若为数组,递归调用 faltten,并将结果与newarr合并
for (var t of arr) {
if (!Array.isArray(t)) {
newarr.push(t);
} else {
newarr.concat(flatten(t))
}
}
return newarr
}
}
var flatten = product();
console.log(flatten(arr))
- toString & split 调用数组的toString方法,将数组变为字符串然后再用split分割还原为数组 var arr=[1,[2,3,[4,5]]]; function flatten(arr) { return arr.toString().split(',').map(function(item) { return Number(item); }) } alert(flatten(arr));//[1,2,3,4,5]
- concat
var arr=[1,[2,3,[4,5]]];
function flatten(arr) {
var res = [];
arr.map(item => {
if(Array.isArray(item)) {
res = res.concat(flatten(item));
} else {
res.push(item);
}
});
return res;
}
alert(flatten(arr));//[1,2,3,4,5]
- 扩展运算符 [].concat(...[1, 2, 3, [4, 5]]); // [1, 2, 3, 4, 5] 根据这个结果我们可以做一个遍历,若arr中含有数组则使用一次扩展运算符,直至没有为止。 function flatten(arr) { while(arr.some(item=>Array.isArray(item))) { arr = [].concat(...arr); } return arr; }
数组去重
- reduce
var newArr = arr.reduce(function (prev, cur) {
prev.indexOf(cur) === -1 && prev.push(cur);
return prev;
},[]);
1.1 reduce+includes
function unique(arr){
return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr));
- set
function unique (arr) {
return Array.from(new Set(arr))
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
或者
const arr=[1,2,2,3,3,4,4,4,5]
console.log([...new Set(arr)] ) // [1, 2, 3, 4, 5]
- filter
function unique(arr) {
return arr.filter(function(item, index, arr) {
//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
return arr.indexOf(item, 0) === index;
});
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
- indexOf
var a = [1, 2, 2, 3, 3, 4, 4, 4, 5]
var b = []
for (var i = 0; i < a.length; i++) {
if(b.indexOf(a[i]) === -1){
b.push(a[i])
}
}
console.log(b) // [1, 2, 3, 4, 5]
数组复制
- for循环
var a = [1,2,3]
var a1 = []
for (i=0; i<a.length; i++){
a1.push(a[i])
}
a1.push(4)
alert(a1)//[1,2,3,4]
或者 for of 循环遍历
var a = [1,2,3]
var a1 = []
for (let val of a){ //不能用for in,它遍历的是索引(即键名)
a1.push(val)
}
a1.push(4)
alert(a1)//[1,2,3,4]
- concat
var a = [1,2,3]
var a1 = a.concat()
a1.push(4)
alert(a1)//[1,2,3,4]
- ES6扩展运算符 或Array.from()
var a = [1,2,3]
var a1 = [...a]
a1.push(4)
alert(a1)//[1,2,3,4]
var a = [1,2,3]
var a1 = Array.from(a)
a1.push(4)
alert(a1)//[1,2,3,4]
- slice
var a = [1,2,3]
var a1 = a.slice(0)
a1.push(4)
alert(a1)//[1,2,3,4]
删除数组
- splice 会改变原数组
var arr = [1, 2, 3, 4];
arr.splice(3,1);
console.log(arr[3]);//undefined
console.log(arr); //[1, 2, 3]
- delete 删除元素不改变length
var arr = [1, 2, 3, 4];
delete arr[0];
console.log(arr[0]);//undefined
console.log(arr); //[empty, 2, 3, 4]
- 直接改变length
var colors = ["red", "blue", "grey"]; //创建一个包含3个字符串的数组
colors.length = 2;
console.log(colors[2]); //undefined
console.log(colors) // ["red", "blue"]
- ForEach循环来对比元素找到之后将其删除:
var colors = ["red", "blue", "grey"];
colors.forEach(function(item, index, arr) {
if(item == "red") {
arr.splice(index, 1);
}
});
console.log(colors); //["blue", "grey"]
- filter:
var colors = ["red", "blue", "grey"];
colors = colors.filter(function(item) {
return item != "red"
});
console.log(colors); //["blue", "grey"]
参考文章: