/* 复习数组常用api 问题? 1.类型化数组 */ // 创建一个数组 let arr = new Array(1, 2, 3, 4, 5, 6) // 使用构造函数创建 let arr2 = [1,2,3,4,5,6,76,7] // 使用字面量 // 静态方法 // Array.form() Array.from() 静态方法从可迭代或类数组对象创建一个新的浅拷贝的数组实例。 let arrByFrom = Array.from({length: 10}, ()=>1) // 使用类数组来创建一个数组 let setList = new Set(); // set是一个可迭代对象,实现了iterator接口 setList.add(1); setList.add(2); setList.add(3); let arrByFrom2 = Array.from(setList) // 将一个迭代对象转换为一个数组 let arrByFrom3 = Array.from(setList, (item, index)=> { // 第二个参数接收一个函数,将返回值作为初始值,回调函数的第一个参数为当前值,第二个参数为当前值在创建数组中的下标 return item * index }) // Array.isArray() // console.log(Array.isArray(arr)) // 判断一个数据是非是数组 // console.log( Array.of(1,2,3) ) // 通过参数创建数组返回 【1,2,3】 // 实例方法 Array.prototype.at(), 接受一个整数下标返回下标内容 // console.log(arr.at(-1)) // 可接受正数和负数arr.at(1) = 2 arr.at(-1) = 6 // console.log(arr.concat(arr2)) // 返回合并之后的新数组, 可实现数组的浅拷贝 // Array.prototype.entries() 可以返回数组的迭代对象[index, item] // for (let [index, item] of arr.entries()) { // console.log(index + "---" + item) // } // Array.prototype.every(fn) fn 返回一个布尔值,如果全部符合条件则every返回true // 判断数组的所有内容是否大于0 // console.log(arr.every((v)=>v>0)); // 对类数组同样生效 // let arrInObject = {length: 3, 0: 1, 1: 2, 2: 3} // console.log(Array.prototype.every.call(arrInObject, (item)=>typeof item === "number")); // Array.prototype.fill(value, start, end) 使用一个静态的值填充数组,可以指定开始和结束位置,没有指定则填充全部 // console.log(Array(10).fill(2,0,10)) // 也可以填充类数组,会读取类数组的length // console.log(Array.prototype.fill.call({length: 10}, 2)); // Array.prototype.filter(fn(item, index, arr)) 返回匹配条件的数组,如果没有则返回"[]" // console.log(arr.filter((value)=> value> 3)); //console.log([1,,,,3].filter((value)=> value === undefined)); // 遇到空槽时是不会处理的 // Array.prototype.find(fn) 根据fn的判断返回元素, 若没有找到则返回undefined // console.log([{id: 1, name: '小明'}, {id: 2, name: '小王'}].find((v)=>v.id===1)); // Array。prototype.findLast(fn) 会返回最后一个下标 // Array.prototype.findIndex(fn) 根据条件,找到第一个符合要求的第一个下标 // console.log(arr.findIndex((v)=> v>2)); // Array.prototype.findLastIndex(fn) 根据条件,找到第一个符合要求的最后一个下标 // console.log(arr.findLastIndex((v)=> v>2)); // Array.prototype.indexOf(value) 根据给定的具体值,返回此值在数组中的小标,和findIndex的区别是不需要使用测试函数 // console.log(arr.indexOf(2)); // Array.prototype.includes(value, 开始搜索的位置) 返回一个布尔值,如果value存在在这个数组中,那么返回true // console.log(arr.includes(1, -1)); // 显然在-1开始的位置没有一个数是1,所以返回false // Array.prototype.some(fn) 这个和every相反,只要有一个符合条件就返回true // console.log(arr.some((value)=>value>1)); // Array.prototype.flat(int) 可以展平一个数组,参数为要展开至多少层 // console.log([1,[2,[3,[4,[5]]]]].flat(2)); // [ 1, 2, 3, [ 4, [ 5 ] ] ] // 当传入Infinity时会全部展开 // console.log([1,[2,[3,[4,[5]]]]].flat(Infinity)); // [ 1, 2, 3, 4, 5 ] // Array.prototype.forEach 会遍历数组中的每一个元素,如果想对原数组进行操作可以使用这个方法 // arr.forEach((value, index, arr)=>{ // console.log(`arr[${index}] = ${value}`) // }) // 使用forEach对数组进行扁平化 // let flaten = (arr)=>{ // const flatArr = [] // arr.forEach(item=>{ // if(Array.isArray(item)) { // flatArr.push(...flaten(item)) // }else{ // flatArr.push(item) // } // }) // return flatArr // } // console.log(flaten([1,[2,[3,[4,[5]]]]])); // Array.prototype.join(). 可以将一个数组用指定的字符链接起来,默认是逗号 // console.log([1,2,3,4,5].join("hh")); // Array.prototype.keys() 会返回数组所有的index,缺失数组的也会返回 // console.log([...[4,5,,6].keys()]); // console.log(Object.keys([4,5,,6])); // 缺失项的下标是不会返回的 // Array.prototype.map() 当需要对数组进行格式化,又不需要对原数组操作时可以使用这个方法 // console.log([[1,'小明'], [2, '小红'], [3, '小王']].map((item)=>({ id: item[0], name: item[1]}))); // pop,push,shift,unshift 可以添加或者修改元素,可以实现队列和栈的数据结构 // console.log(arr.push(1)); // 在末尾添加一个元素,并且添加后数组的长度 // console.log(arr.pop()); // 删除末尾的元素并且返回它 // console.log(arr.shift()); // 删除数组的第一个元素,并且返回它 // console.log(arr.unshift(8)); // 插入一个元素到数组的第一个位置,并且返回新数组的长度 // Array.prototype.reduce(fn) // 对数组中的每一个元素进行fn操作,并将返回值作为下一次函数的参数,最终返回这个值 // 使用reduce对数组内容求和 // console.log([1,2,3,4,5].reduce((acc,cur)=> acc + cur)); // 当没有给初始值时使用数组第一个值作为acc,cur从第二个值开始,之后的acc为之前函数返回的值 // 思考这样一个问题我有一个对象数组,对象数组中的每一个对象元素都有一个money的属性,想在我想对这样一个属性求将如何操作,在不给初始值的情况下显然是不可以操作的,因为在没有给初始值的情况下第一次的acc为数组中的第一个元素,显然不能作求和操作,这个时候就需要设置一个初始值 // console.log([{id: 1, money:399}, {id: 2, money: 699}, {id: 3, money: 800}].reduce((acc, cur)=> acc + cur.money, 0)); // reduce是非常强大的,可以做非常多的操作,再来想一想,这样一个操作,我想对下面这样一个对象数组进行条件格式化,当数组中id大于2的元素做一次格式化操作 let testArr = [{id: 1, age: 17}, {id: 2, age: 19},{id: 3, age: 20},{id: 4, age: 17}] // 可以使用filter先过滤,再使用map // console.log(testArr.filter(item=>item.id > 2).map(item=> { // if(item.age > 18) { // return {...item, isAdult: true} // }else { // return {...item, isAdult: false} // } // })); // 这样写有一个坏处,就是有两遍循环,数据量一大,就还慢,下面使用reduce一次性完成 // console.log(testArr.reduce((acc, cur)=> { // if(cur.id <= 2) return acc // if (cur.age > 18) { // return [...acc, {...cur, isAdult: true}] // } // return [...acc, {...cur, isAdult: false}] // }, [])); // reduce 还可以使二维数组展平 // console.log([[2],[2],[4],[5]].reduce((acc, cur)=>{ // return acc.concat(cur) // }, [])); // reduce对数组对象进行分组, 比如上面的testArr,我们将将年龄来进行分组,17岁的一组,20岁的一组 // 普通实现 // let groupByAge = {} // testArr.forEach(item => { // if(groupByAge[item.age]) { // groupByAge[item.age].push(item) // }else { // groupByAge[item.age] = [item] // } // }) // console.log(groupByAge); // 使用reduce,可以不借助外部变量 // console.log(testArr.reduce((acc, cur)=> { // acc[cur.age] ? acc[cur.age].push(cur) : acc[cur.age] = [cur] // return acc // }, {})); // reduceRight 和reduce类似,只不过是从右边开始遍历 // Array.prototype.reverse() 会翻转数组, 并且会对原数组直接操作 // console.log([1,2,3,4,5].reverse()); // Array.prototype.slice(start, end) 切截取数组的一部分返回,会做浅拷贝 // console.log([1,2,3,4].slice(2,4)); // console.log([1,2,3,4,5,6].slice(-2)) // 截取最后的两个元素 // 在es6之前,可以使用slice实现类数组转换为数组 // console.log(Array.prototype.slice.call({length:3, 0: 1, 1: 2, 2: 3})); // Array.prototype.sort() 可以对数组内容排序,默认是根据UTF16字符编码排序的 // console.log([1,111,2,222,3].sort()); // sort接收一个比较器,会传递两个参数a,b,当返回的值小于0时a会排在b的前面,当返回的值大于0时a会排在b的后面 // console.log([1,111,2,222,3].sort((a,b)=>{ // if(aa-b)) // 反之可以写成(a,b)=> b-a 来实现倒序排序 // console.log([1,111,2,222,3].sort((a,b)=>b-a)) // 在es2019也就是es10之前,这个排序可能是不稳定的,因为规范没有要求是否要稳定排序,各家的实现也不一样,所以可能稳定,也可能不稳定 // Array.prototype.Splice(start, 删除的个数, 内容) // let spliceArr = [1,2,3,4] // spliceArr.splice(1,1) // 从第二个元素开始,删除一个 [ 1, 3, 4 ] // spliceArr.splice(1) // 删除第二个元素之后的所有元素 // spliceArr.splice(1,0,4,5,6) // 从第二个位置插入数据 // spliceArr.splice(1,1,4,5,6) // 从第二个位置插入数据并且覆盖原本的第二个数 // spliceArr.splice(-1) // 删除倒数第一个数 // spliceArr.splice(spliceArr.length, 0,5) // 在原数组的后面添加一个数值,可实现push功能 // spliceArr.splice(0,0,0) // 在数组的最前面添加一个数值,可实现unShift() // console.log(spliceArr); // Array.prototype.values() 返回数组值的迭代对象