Array的总结
本文资料参考:DMN, JAVASCRIPT.INFO
-
前言 ——索引 和 length
//length 属性的值是数组中索引元素的索引加1, //来看这里 let fruits = []; fruits[123] = "Apple"; alert( fruits.length ); // 124 -------------------------------------------------------------------------------------------- //length 属性的另一个有意思的点是它是可写的。 //如果我们手动增加它,则不会发生任何有趣的事儿。但是如果我们减少它,数组就会被截断。该过程是不可逆的,下面是例子: let arr = [1, 2, 3, 4, 5]; arr.length = 2; // 截断到只剩 2 个元素 alert( arr ); // [1, 2] arr.length = 5; // 又把 length 加回来 alert( arr[3] ); // undefined:被截断的那些数值并没有回来
所以清空数组可以使用
arr.length = 0
,//同时也可以使用arr[arr.length-1]取到数组的最后一项,但是这样的写法比较麻烦, 可以使用arr.at(-1)
个人将js的数组操作大致分为:增、删、改、查、遍历、去重,拷贝。
增,删
-
push 添加元素至数组末尾
-
pop
删除arr中末尾元素,并返回该元素 -
unshift
再arr头部添加元素 -
shift 删除arr头部元素,并返回该元素
-
splice(start, deleteCount, item)
- 以数组形式返回被修改的内容。此方法会改变原数组。start: 开始位置,deleteCount:要删除元素,item:要增加元素
-
slice(startNum,endNum) 截取数组
-
fill
//fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。 arr.fill(value[, start[, end]]) value:用来填充的值 start:起始索引, end:终止索引 const array1 = [1, 2, 3, 4]; // fill with 0 from position 2 until position 4 console.log(array1.fill(0, 2, 4)); // expected output: [1, 2, 0, 0]
改
-
join(str)
根据参数规则返回新的字符串 不改变原数组 -
splice:(上方介绍)
-
filter : (下方介绍)
-
排序
-
sort(fun) 排序,参数为规定排序方式的函数
// function 参数为一个函数体 函数体接收两个形参 // 不传参数 根据ASCII码表 来比较数组中的第一个值排序 ------------------------------------------------------------------------ let arr = [22,44,11,33,55] arr.sort(function(a,b){ return a - b //从小到大排列 return b - a //从达到小排列 })
-
reverse()反向排序,改变原数组
-
-
flat 将多维数组元素合并至新数组,并将之返回,使用infinity可以展开任意深度嵌套数组
//flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。 const arr1 = [0, 1, 2, [3, 4]]; console.log(arr1.flat()); // expected output: [0, 1, 2, 3, 4] const arr2 = [0, 1, 2, [[[3, 4]]]]; console.log(arr2.flat(2)); // expected output: [0, 1, 2, [3, 4]] //使用 Infinity,可展开任意深度的嵌套数组 var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]]; arr4.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
查
-
in 运算符,建议使用于obj
//检查某个键名是否存在的运算符in,适用于对象,也适用于数组。 var arr = [ 'a', 'b', 'c' ]; 2 in arr // true '2' in arr // true 4 in arr // false
-
arr.indexOf(item, from)
—— 从索引from
开始搜索item
,如果找到则返回索引,否则返回-1
。 -
arr.includes(item, from)
—— 从索引from
开始搜索item
,如果找到则返回true
(译注:如果没找到,则返回false
)。-
方法
includes
的一个次要但值得注意的特性是,它可以正确处理NaN
,这与indexOf
不同:const arr = [NaN]; alert( arr.indexOf(NaN) ); // -1(错,应该为 0) alert( arr.includes(NaN) );// true(正确)
不加参数时,默认从零开始
在数组为对象数组时
-
-
find
: 找到具有特定条件的对象?这时可以用arr.find
方法。//`find` 方法搜索的是使函数返回 `true` 的第一个(单个)元素。 let result = arr.find(function(item, index, array) { // 如果返回 true,则返回 item 并停止迭代 // 对于假值(falsy)的情况,则返回 undefined }); //item 是元素。 //index 是它的索引。 //array 是数组本身。 ------------------------------------------------------------------------ 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
-
arr.findIndex
方法(与arr.find
)具有相同的语法,但它返回找到的元素的索引,而不是元素本身。如果没找到,则返回-1
。 -
arr.filter(fn)
//如果需要匹配的有很多,我们可以使用 arr.filter(fn),语法与 `find` 大致相同,但是 `filter` 返回的是所有匹配元素组成的数组:
let results = arr.filter(function(item, index, array) {
// 如果 true item 被 push 到 results,迭代继续
// 如果什么都没找到,则返回空数组
});
------------------------------------------------------------------------
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
// 返回前两个用户的数组
let someUsers = users.filter(item => item.id < 3);
alert(someUsers.length); // 2
同时如果有向数组中元素添加字段的需求,也是可以使用filter来添加
arr.filter(item => {
item.replay = true;
})
遍历
实际应用中我们需要对数组中的每一项都进行操作,遍历是必不可少的一环
-
基础for循环
-
for…of…
//在for..of循环中,item为数组的元素 for (const item of Arr) { // ... do something }
-
for…in…
//在for..in循环中,index为数组元素的下标 for (const index of Arr) { // ... do something }
-
forEach
//arr.forEach 方法允许为数组的每个元素都运行一个函数。 arr.forEach(function(item, index, array) { // ... do something with item }); //item为元素,index为下标,array为要遍历的数组 ------------------------------------------------------------------------ let arr = ["Bilbo", "Gandalf", "Nazgul"] arr.forEach((item, index, array) => { alert(`${item} is at index ${index} in ${array}`); }); //Bilbo is at index 0 in Bilbo,Gandalf,Nazgul //Gandalf is at index 1 in Bilbo,Gandalf,Nazgul //Nazgul is at index 2 in Bilbo,Gandalf,Nazgul
-
map… 返回结果数组
//arr.map 方法是最有用和经常使用的方法之一。 //它对数组的每个元素都调用函数,并返回结果数组。 let result = arr.map(function(item, index, array) { // 返回新值而不是当前元素 }) ------------------------------------------------------------------------ let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length); alert(lengths); // 5,7,6 ------------------------------------------------------------------------ let arr = [ [1,2,5,6], [2,8,9,6], [7,8,9,4], ] let arr1 = arr.map(item => item[0]) //alert(arr1) [1,2,7]
-
Reduce
//累加 let value = arr.reduce(function(accumulator, item, index, array) { // accumulator —— 是上一个函数调用的结果,第一次等于 initial(如果提供了 initial 的话)。 //item —— 当前的数组元素。 //index —— 当前索引。 //arr —— 数组本身。 //initial ——初始值 }, [initial]); ---------------------------------------------------------------------------- let arr = [1, 2, 3, 4, 5]; let result = arr.reduce((sum, current) => sum + current, 0); alert(result); // 15 //这里的sum就是accumulator参数,
-
every
//every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。 //需要注意的是如果该方法接收到的数组为空数组,则会返回true -------------------------------------------------------------------------------- const isBelowThreshold = (currentValue) => currentValue < 40; const array1 = [1, 30, 39, 29, 10, 13]; console.log(array1.every(isBelowThreshold)); // expected output: true
-
some
//some() 方法测试数组中是不是至少有 1 个元素通过了被提供的函数测试。它返回的是一个 Boolean 类型的值。 //需要注意的是 如果数组为空,则返回false -------------------------------------------------------------------------------------------- const array = [1, 2, 3, 4, 5]; const even = (element) => element % 2 === 0; console.log(array.some(even)); // expected output: true
去重
这里的去重方式无限制
这里数组去重用到了es6的set和map,统一在这里简单说明
- set
//ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。
const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
console.log(i);
}
-
map
//ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应, map.has(key) //有返回true,无则fanhuifalse map.set(key,value) //设置值
-
Array.from()
//使用此方法去重之前,应该了解此方法的具体使用。 //Array.from() 方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
[...new Set(array)] //es6去重
function unique(array) { return Array.from(new Set(array)); } unique([1, 1, 2, 3, 3]); // => [1, 2, 3] //首先,new Set(array) 创建了一个包含数组的集合,Set 集合会删除重复项。因为 Set 集合是可迭代的,所以可以使用 Array.from() 将其转换为一个新的数组。
-
includes 和indexOf去重相似,后续不再赘述
function removeDuplicate(arr) { const newArr = [] arr.forEach(item => { if (!newArr.includes(item)) { //判断条件更换为indexOf newArr.push(item) } }) return newArr } const result = removeDuplicate(arr) console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]
-
使用Map()
function removeDuplicate(arr) { const map = new Map() const newArr = [] arr.forEach(item => { if (!map.has(item)) { // has()用于判断map是否包为item的属性值 map.set(item, true) // 使用set()将item设置到map中,并设置其属性值为true newArr.push(item) } }) return newArr } const result = removeDuplicate(arr) console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]
拷贝
-
es6 浅拷贝
let arr4 = [1,2,3,4,5,{ 'dsf': 456 }] let arr5 = [...arr4]
-
JSON.stringify() 和JSON.parse()
深拷贝,函数拷贝不了 -
slice方法 浅拷贝
var arr = [1,2,3,4,5] var arr2 = arr.slice(0)
后续和对象那里一块说吧。
判断类型
-
Array.isArray()
alert(Array.isArray({})); // false alert(Array.isArray([])); // true
-
Object.prototype.toString.call(xxx)
{}.toString.call(val).slice(8,-1).toLowerCase();