数组
1、数组是一个无序元素的紧密结构的有序列表
2、数组中每个槽位可以存储任意类型的数据。它的第一个元素是字符串,第二个元素是数值,第三个是对象。
3、数组也是动态大小的,会随着数据添加而自动增长
4、length 属性会自动被创建,当length=0 时相当于删除数组
5、arr.length 是一个可读可写不可删除不可枚举的属性
6、arr.length–;delete arr.length删除数组的最尾部元素/删除数组
创建函数的几种方式
Array 构造函数(实例化)
let colors = new Array(20);
let colors = new Array("red", "blue", "green");
let colors = new Array(3);
let names = new Array("Greg");
let colors = Array(3);
let names = Array("Greg");
数组字面量
与对象一样,在使用数组字面量表示法创建数组不会调用Array 构造函数
let colors = ["red", "blue", "green"];
let names = [];
let values = [1,2,];
随机颜色
function randomColor(){
return "#"+Array(6).fill(1).map(function(){
return (~~(Math.random()*16)).toString(16)
}).join("");
}
function randomColor(){
return Array(6).fill(1).reduce(function(value,item){
return value+(~~(Math.random()*16)).toString(16);
},"#")
}
for in
1、当把数组作为对象枚举遍历时,数组中下标就变为对象的key属性,对象key属性就是字符串
2、for in最好不要作为数组遍历方式使用,会遍历到数组的所有属性,包括对象属性
数组方法
数组方法会操作两种情况
1、改变原数组
? 2、不改变原数组,操作产生新数组
fill
fill(value[, start[, end]])
插入一个或者多个元素,返回新数组的长度
1、向一个已有的数组中插入全部或部分相同的值
2、开始索引用于指定开始填充的位置,它是可选的。
3、如果不提供结束索引,则一直填充到数组末尾。
4、负值索引从数组末尾开始计算
5、使用fill填入的是对象引用地址
基础
const zeroes = [0, 0, 0, 0, 0];
zeroes.fill(5);
console.log(zeroes);
zeroes.fill(0);
zeroes.fill(6, 3);
console.log(zeroes);
zeroes.fill(7, 1, 3);
console.log(zeroes);
zeroes.fill(8, -4, -1);
console.log(zeroes);
const zeroes = [0, 0, 0, 0, 0];
zeroes.fill(1, -10, -6);
console.log(zeroes);
zeroes.fill(1, 10, 15);
console.log(zeroes);
zeroes.fill(2, 4, 2);
console.log(zeroes);
zeroes.fill(4, 3, 10)
console.log(zeroes);
fill构造
1、Array不是数组时报错
2、start 非数值时start=0
3、start < 0
4、end 非数值时end=arr.length
5、end < 0
6、end > arr.length
7、start遍历到end
8、强制转换start和end为数值
9、返回新数组
function arrayFill(arr,value,start,end){
if(!arr || arr.constructor!==Array) throw new Error(arr+"is not Array!");
start=~~start
if(isNaN(end)) end=arr.length;
end=parseInt(end);
if(start<0) start=start+arr.length<0 ? 0 : start+arr.length;
if(end<0) end=end+arr.length<0 ? 0 : end+arr.length;
if(end>arr.length) end=arr.length;
for(var i=start;i<end;i++){
arr[i]=value;
}
return arr;
}
push
push()方法接收任意数量的参数,并将它们添加到数组末尾,返回数组的最新长度。
1、Array不是数组时报错
2、添加数值为1个时,返回数组长度
3、添加数值
4、返回数组长度
function arrayPush(arr) {
if (!arr || arr.constructor !== Array) throw new Error(arr + "is not Array!");
if (arguments.length === 1) return arr.length;
for (var i = 1; i < arguments.length; i++) {
arr[arr.length] = arguments[i];
}
return arr.length;
}
pop
pop()方法则用于删除数组的最后一项,同时减少数组的length 值,返回被删除的项。
1、Array不是数组时报错
2、删除无元素时返回undefined
3、删除元素并且减少数组长度
4、返回删除元素
function arrayPop(arr) {
if (!arr || arr.constructor !== Array) throw new Error(arr + "is not Array!");
if (arr.length === 0) return;
var item = arr[arr.length - 1];
arr.length--;
return item;
}
unshift
在元素头部添加一个或者多个元素,修改原数组,返回新数组长度
1、Array不是数组时报错
2、len===0时返回数组新长度
3、添加数组分析
for (var i = arr.length + len - 1; i >= 0; i–) { if (i - len >= 0) arr[i] = arr[i - len]; else arr[i] = arguments[i + 1]; }
4、返回新数组长度
function arrayUnshift(arr) {
if (!arr || arr.constructor !== Array) throw new Error(arr + "is not Array!");
var len = arguments.length - 1;
if (!len) return arr.length;
for (var i = arr.length + len - 1; i >= 0; i--) {
if (i - len >= 0) arr[i] = arr[i - len];
else arr[i] = arguments[i + 1];
}
return arr.length;
}
shift
shift()删除数组的第一项并返回删除数值,然后数组长度减1。
1、Array不是数组时报错
2、删除无元素时返回undefined
3、删除元素并且移动剩下数组
4、返回删除元素
function arrShift(arr) {
if (!arr || arr.constructor !== Array) throw new Error(arr + "is not Array!");
if (arr.length === 0) return;
var item = arr[0];
for (var i = 0; i < arr.length - 1; i++) {
arr[i] = arr[i + 1];
}
arr.length--;
return item;
}
concat
concat()方法可以在现有数组全部元素基础上创建一个新数组。
首先,会创建一个当前数组的副本,
然后,再把它的参数添加到副本末尾,
最后,返回这个新构建的数组。
如果传入一个或多个数组,则concat()会把这些数组的每一项都添加到结果数组。
如果参数不是数组,则直接把它们添加到结果数组末尾。
1、Array不是数组时报错
2、arr产生新数组,复制数组
3、添加arguments里的元素(核心array[array.length]=arguments[ i ][ j ];)
4、返回新数组
divs=[].concat.apply([],divs);
console.log(divs);
function arrayConcat(arr){
if (!arr || arr.constructor !== Array) throw new Error(arr + "is not Array!");
var array=[];
for(var i=0;i<arguments.length;i++){
if(arguments[i] && arguments[i].constructor===Array){
for(var j=0;j<arguments[i].length;j++){
array[array.length]=arguments[i][j];
}
}else{
array[array.length]=arguments[i];
}
}
return array;
}
join
如果不给join()传入任何参数,或者传入undefined,则仍然使用逗号作为分隔符。
如果数组中某一项是null 或undefined,则在join()返回的结果中会以空字符串表示。
返回值为String
1、Array不是数组时报错
2、separator(填充符)为undefined或者null情况
3、将separator转换为String
4、设置空字符串接受连接数组。
var arr=[1,2,3,4,5,6,7,8];
console.log(arr.join());
console.log(arr.join("#"));
console.log(arr.join("+"));
console.log(arr.join(undefined));
console.log(arr.join(null));
function arrayJoin(arr,separator){
if(!arr || arr.constructor!==Array) throw new Error(arr+"not is Array");
if(separator===undefined) separator=",";
separator=String(separator);
var str="";
for(var i=0;i<arr.length;i++){
if(i===arr.length-1) return str+=arr[i];
str+=arr[i]+separator;
}
}
slice
slice( begin [, end] )
用于创建一个包含原有数组中一个或多个元素的新数组。slice()方法不影响原始数组,返回新数组。
slice()方法接收一个或两个参数:返回元素的开始索引和结束索引。
如果只有一个参数,则slice()会返回该索引到数组末尾的所有元素。
如果有两个参数,则slice()返回从开始索引到结束索引对应的所有元素,其中不包含结束索引对应的元素。
如果slice()的参数有负值,那么就以数值长度加上这个负值的结果确定位置。
如果结束位置小于开始位置,则返回空数组。
1、Array不是数组时报错
2、判断start 、end 是否为字符串
3、转换判断start为Number 转换end为parseInt
4、判断start<0 , end<0
5、截取数组
6、返回新数组,不改变原数组
function arraySlice(arr,start,end){
if(!arr || arr.constructor!==Array) throw new Error(arr+"not is Array");
start =~~start;
end=parseInt(end);
start=Number(start);
start= start <0 ? (start+arr.length<0 ? 0 : start+arr.length) : start;
end=end<0 ? (end+arr.length<0 ? 0 : end+arr.length) : end ;
var arr1=[];
for(var i=start;i<end;i++){
arr1[arr1.length]=arr[i];
}
return arr1;
}
splice
splice( start , [deleteCount , item1, item2, …])
splice()方法始终返回这样一个数组,从数组中被删除的元素(如果没有删除元素,则返回空数组)。
返回新数组,改变原数组
作用
? 删除。需要给splice()传2 个参数:splice(0, 2)会删除前两个元素。 ? 插入。需要给splice()传3 个参数:splice(2, 0, “red”, “green”)会从数组位置2 开始插入字符串"red"和"green"。 ? 替换。splice(2, 1, “red”, “green”)会在位置2 删除一个元素,然后从该位置开始向数组中插入"red"和"green"。
1、Array不是数组时报错
2、判断start 是否为字符串
3、若为start===undefined返回为 [ ]
4、判断start<0 , deleteCount<0
5、 判断deleteCount是否是undefined 删除到尾部
6、创建新数组存放删除的数组
7、deleteCount超出数组长度时全部删除
8、插入元素,返回新数组。
function arraySplice(arr,start,deleteCount){
if(!arr || arr.constructor!==Array) throw new Error(arr+"not is Array");
if(start===undefined) return [];
start=~~start;
if(start<0) start=(start+arr.length)<0 ? 0 : start+arr.length;
if(deleteCount===undefined) deleteCount=arr.length-start;
deleteCount=~~deleteCount;
if(deleteCount<0) deleteCount=0;
if(deleteCount+start>arr.length) deleteCount=arr.length-start;
var arr1=[];
for(var i=start;i<arr.length;i++){
if(i<start+deleteCount)arr1[arr1.length]=arr[i];
arr[i]=arr[i+deleteCount];
}
arr.length-=deleteCount;
var len=arguments.length-3;
if(len<=0) return arr1;
for(var j=arr.length-1+len;j>=start;j--){
if(j>=start+len) arr[j]=arr[j-len];
else arr[j]=arguments[3+j-start];
}
return arr1;
}
indexOf
indexOf( searchElement [ , fromIndex] )
indexOf()从数组前头(第一项)开始向后搜索indexOf()返回要查找的元素在数组中的位置,如果没找到则返回 -1。
可以有两个参数,第一个为查找元素,第二个为第几项
负数是从后往前查找
1、Array不是数组时报错
2、判断fromStart是否为字符串
3、fromStart< 0
4、(fromStart + arr.length) < 0
5、 查找情况 (空元素)
6、返回-1或者元素索引
var index=-1;
while(~(index=arr.indexOf(2,index+1))) console.log(index);
function arrayIndexOf(arr, item, fromStart) {
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
fromStart = ~~fromStart;
if (fromStart < 0) fromStart = (fromStart + arr.length) < 0 ? 0 : fromStart + arr.length;
for (var i = fromStart; i < arr.length; i++) {
if (!(i in arr)) continue;
if (arr[i] === item) return i;
}
return -1;
}
lastIndexOf
lastIndexOf(searchElement [, fromIndex] )
lastIndexOf()接收两个参数:要查找的元素和一个可选的起始搜索位置。
lastIndexOf()都返回要查找的元素在数组中的位置,如果没找到则返回 - 1。
1、Array不是数组时报错
2、判断fromEnd是否为undefined或者字符串
3、fromEnd< 0
4、(fromEnd+ arr.length) < 0
5、 查找情况 (空元素)
6、返回-1或者元素索引
function arrayLastIndexOf(arr, item, fromEnd) {
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
if (fromEnd === undefined) fromEnd = arr.length - 1;
fromEnd = ~~fromEnd;
if (fromEnd < 0) fromEnd = (fromEnd + arr.length) < 0 ? 0 : fromEnd + arr.length;
for (var i = fromEnd; i >= 0; i--) {
if (!(i in arr)) continue;
if (arr[i] === item) return i;
}
return -1;
}
includes
includes( item [ , fromIndex])
includes()都接收两个参数:要查找的元素和一个可选的起始搜索位置。includes()方法从数组前头(第一项)开始向后搜索includes()返回布尔值,表示是否至少找到一个与指定元素匹配的项。
1、Array不是数组时报错
2、 查找情况 (空元素)
3、返回-1或者元素索引
function arrayIncludes(arr, item) {
for (var i = 0; i < arr.length; i++) {
if (!(i in arr)) continue;
if (arr[i] === item) return true;
}
return false;
}
其他案例
元素计数
var obj={};
for(var i=0;i<arr.length;i++){
if(!(i in arr)) continue;
if(!obj[arr[i]])obj[arr[i]]=0;
obj[arr[i]]++;
}
数组去重
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;){
if(arr[i]===arr[j]) arr.splice(j,1);
else j++;
}
}
var arr1=[];
xt: for(var i=0;i<arr.length;i++){
for(var j=0;j<arr1.length;j++){
if(arr1[j]===arr[i]) continue xt;
}
arr1.push(arr[i]);
}
var arr1=[];
for(var i=0;i<arr.length;i++){
if(arr1.indexOf(arr[i])<0) arr1.push(arr[i])
}
var arr1=[];
for(var i=0;i<arr.length;i++){
if(!(~arr1.indexOf(arr[i]))) arr1.push(arr[i])
}
var arr1=[];
for(var i=0;i<arr.length;i++){
if(!arr1.includes(arr[i])) arr1.push(arr[i])
}
将两个数组中相同元素放在一个新数组中
var arr = [1, 2, 3, 2, , 3, 1, 2, 6, 3, 2, 1, 2, 7, 5, 7, 8, 3, 4];
var arr1 = [2, 5, 10, 4];
var arr2=[];
for(var i=0;i<arr.length;i++){
if(arr1.includes(arr[i]) && !arr2.includes(arr[i])) arr2.push(arr[i]);
}
console.log(arr2)
将两个数组中不同的元素放在一个新数组中
var arr2 = [];
function difer(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length;) {
if (arr[i] === arr[j]) arr.splice(j, 1);
else j++
}
}
return arr;
}
arr=difer(arr).concat(difer(arr1));
function getCountObj(arr){
var obj={};
for(var i=0;i<arr.length;i++){
if(!(i in arr)) continue;
if(!obj[arr[i]])obj[arr[i]]=0;
obj[arr[i]]++;
}
return obj
}
arr=difer(arr).concat(difer(arr1));
var obj=getCountObj(arr);
for(var i=0;i<arr.length;i++){
if(!(i in arr)){
arr2.length++;
continue;
}
if(obj[arr[i]]>1) continue;
arr2.push(arr[i]);
}
迭代方法
每个方法接收两个参数:以每一项为参数运行的函数,以及可选的作为函数运行上下文的作用域对象(影响函数中this 的值)。
传给每个方法的函数接收3个参数:数组元素、元素索引和数组本身。因具体方法而异,这个函数的执行结果可能会也可能不会影响
方法的返回值。
这些方法都不改变调用它们的数组
forEach
forEach ( function ( item[ , index , arr] ) { }[ , thisArg] )
forEach():对数组每一项都运行传入的函数,=没有返回值==。
try不管运行了多少,只要没有错误之前都是有效的,一旦遇到错误直接执行catch部分语句,不管报不报错都执行finally语句
try{
}catch(e){
}finally{
}
try {
arr.forEach(function (item, index, arr) {
console.log(item,index,arr);
if(item>3) arr1.push(item);
return "a"
if (item === 3) throw new Error("aa");
console.log(item);
})
} catch (e) {
}
重构
1、Array不是数组时报错
2、循环触发条件arr.length
3、空元素跳过
4、回调 fn ( )
5、自定义返回
function arrayForEach(array,fn){
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
for(var i=0;i<arr.length;i++){
if(!(i in arr)) continue;
fn(arr[i],i,arr);
}
}
var arr=[1,2,3,4,5];
arrayForEach(arr,function(item,index,arr){
console.log(item,index,arr);
})
map
map(function (item [, index , array] ) {return new_array } [, thisArg ])
map()方法也会返回一个数组。这个数组的每一项都是对原始数组中同样位置的元素运行传入函数而返回的结果==(新数组)==
1、Array不是数组时报错、创建新数组
2、循环触发条件arr.length
3、空元素跳过
4、回调 arr1[i]=fn(arr[i],i,arr);
5、返回新数组
function arrayMap(arr,fn){
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
var arr1=[];
for(var i=0;i<arr.length;i++){
if(!(i in arr)) continue;
arr1[i]=fn(arr[i],i,arr);
}
return arr1;
}
some
some(function (item[ , index , array] )[ , thisArg] )
对数组每一项都运行传入的函数,如果有一项函数返回true,则这个方法返回true。
1、Array不是数组时报错
2、循环触发条件arr.length
3、空元素跳过
4、判断回调if (fn(arr[i], i, arr))
5、返回boolean
var bool = arr.some(function (item, index, arr) {
return item > 3;
});
function arraySome(arr, fn) {
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
for (var i = 0; i < arr.length; i++) {
if (!(i in arr)) continue;
if (fn(arr[i], i, arr)) return true;
}
return false;
}
every
every(function (item [, index , array] ) [, thisArg] )
对数组每一项都运行传入的函数,如果对每一项函数都返回true,则这个方法返回true。
1、Array不是数组时报错
2、循环触发条件arr.length
3、空元素跳过
4、判断回调 if (!fn(arr[i], i, arr))
5、返回新数组
var bool1 = arr.every(function (item, index, arr) {
return item > 3;
});
function arrayEvery(arr, fn) {
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
for (var i = 0; i < arr.length; i++) {
if (!(i in arr)) continue;
if (!fn(arr[i], i, arr)) return false;
}
return true;
}
filter
filter( fn (element[ , index , array ]) , [thisArg])
对数组每一项都运行传入的函数,函数返回true的项会组成新数组之后返回。
1、Array不是数组时报错、创建新数组
2、循环触发条件arr.length
3、空元素跳过
4、判断回调 if (fn(arr[i], i, arr)) arr1.push(arr[i]);
5、返回新数组
var arr1 = arr.filter(function (item, index, arr) {
return item > 3;
})
function arrayFilter(arr, fn) {
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
var arr1 = [];
for (var i = 0; i < arr.length; i++) {
if (!(i in arr)) continue;
if (fn(arr[i], i, arr)) arr1.push(arr[i]);
}
return arr1;
}
归并方法
两个归并方法:reduce()和reduceRight()。这两个方法都会迭代数组的所有项,并在此基础上构建一个最终返回值。
这两个方法都接收两个参数:对每一项都会运行的归并函数,以及可选的以之为归并起点的初始值。
传给reduce()和reduceRight()的函数接收4 个参数:上一个归并值、当前项、当前项的索引和数组本身(prev, cur, index, array)。这个函数返回的任何值都会作为下一次调用同一个函数的第一个参数。
如果没有给这两个方法传入可选的第二个参数(作为归并起点值),则第一次迭代将从数组的第二项开始,因此传给归并函数的第一个参数是数组的第一项,第二个参数是数组的第二项。
reduce
reduce()方法从数组第一项开始遍历到最后一项
let values = [1, 2, 3, 4, 5];
let sum = values.reduce((prev, cur, index, array) => prev + cur);
console.log(sum);
var sum=arr.reduce(function(value,item,index,arr){
console.log(value,item,index);
return value+item;
})
var sum=arr.reduce(function(value,item,index,arr){
console.log(value,item,index);
return value+item;
},100)
console.log(sum)
重构
1、Array不是数组时报错、判断迭代参数是否未定义
2、循环触发条件arr.length
3、回调迭代参数initValue=fn(initValue,arr[i],i,arr);
4、构建返回结果
function arrayReduce(arr,fn,initValue){
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
var i=0;
if(initValue===undefined){
initValue=arr[0];
i=1;
}
for(;i<arr.length;i++){
initValue=fn(initValue,arr[i],i,arr);
}
return initValue;
}
reduceRight
reduceRight()从最后一项开始遍历至第一项。
1、Array不是数组时报错、判断迭代参数是否未定义
2、循环触发条件arr.length-1
3、回调迭代参数initValue=fn(initValue,arr[i],i,arr);
4、构建返回结果
arr.reduceRight(function(value,item,index,arr){})
function arrayReduceRight(arr,fn,initValue){
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
var i=arr.length-1;
if(initValue===undefined){
initValue=arr[arr.length-1];
i--;
}
for(;i>=0;i--){
initValue=fn(initValue,arr[i],i,arr);
}
return initValue;
}
案例
var arr=[2,3,4,5,6];
var arr1=arr.reduce(function(value,item,i){
value[i]=item+10;
return value;
},[]);
console.log(arr1)
var bool=arr.reduce(function(value,item){
if(item>3) value=true;
return value;
},false)
var bool=arr.reduce(function(value,item){
if(item<=3) value=false;
return value;
},true)
var arr1=arr.reduce(function(value,item){
if(item>3) value.push(item);
return value;
},[]);
var arr = [1, 2, 3, 2, 1, 2, 4, 4, 3, 2, 1, 3, 4];
var obj=arr.reduce(function(value,item){
if(!value[item])value[item]=0;
value[item]++;
return value;
},{});
console.log(obj)
var arr1=arr.reduce(function(value,item){
if(!value.includes(item)) value.push(item);
return value;
},[]);
var list = [
{id: 10001,name: "计算器1",price: 3000,num: 2},
{id: 10002,name: "计算器2",price: 4000,num: 1},
{id: 10003,name: "计算器3",price: 5000,num: 3},
{id: 10004,name: "计算器4",price: 6000,num: 5},
{id: 10005,name: "计算器5",price: 7000,num: 6},
{d: 10006,name: "计算器6",price: 6000,num: 6},
];
var item=list.reduce(function(value,item){
if(item.price===6000 && !value) value=item;
return value;
},null);
console.log(item);
find
从数组的最小索引开始,find()返回第一个匹配的元素,第二个可选的参数,用于指定断言函数内部this 的值。
find((element, index, array):元素、索引和数组本身
方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined
1、Array不是数组时报错、判断迭代参数是否未定义
2、循环触发条件arr.length-1
3、空元素跳过
4、判断回调if(fn(arr[i],i,arr)) return arr[i];
5、返回元素或者undefined
function arrayFind(array,fn){
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
for(var i=0;i<arr.length;i++){
if(!(i in arr)) continue;
if(fn(arr[i],i,arr)) return arr[i];
}
}
findindex
从数组的最小索引开始,findIndex()返回第一个匹配元素的索引。第二个可选的参数,用于指定断言函数内部this 的值。
findIndex((element[, index, array]):元素、索引和数组本身
1、Array不是数组时报错、判断迭代参数是否未定义
2、循环触发条件arr.length-1
3、空元素跳过
4、判断回调if(fn(arr[i],i,arr)) return arr[i];
5、返回元素索引或者-1
function arrayFindIndex(array, fn) {
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
for (var i = 0; i < arr.length; i++) {
if (!(i in arr)) continue;
if (fn(arr[i], i, arr)) return i;
}
return -1;
}
flatMap[ES6]
arr.flatMap()更高效,因为浏览器只需要执行一次遍历,flatMap()在非数组对象的方法返回数组时特别有用
返回值一个新的数组,其中每个元素都是回调函数的结果,并且结构深度 depth 值为1
flatMap(function callback(currentValue [, index , array]) { return new_array } , thisArg)
1、Array不是数组时报错、创建空数组
2、循环触发条件arr.length-1
3、空元素跳过
4、设置item=fn(arr[i],i,arr);、连接arr1 arr1=arr1.concat(fn(arr[i],i,arr))
5、返回新数组
function arrayFlatMap(array,fn){
if (!arr || arr.constructor !== Array) throw new Error(arr + "not is Array");
var arr1=[];
for(var i=0;i<arr.length;i++){
if(!(i in arr)) continue;
arr1=arr1.concat(fn(arr[i],i,arr))
}
return arr1;
}
arrayFlatMap(arr,function(){});
var arr=[
[1,2,3,[4,5,6,[7,8,9]]],10,11,[12,13,[14,[15,[16,17,[18,[19]]]]]]
];
function flatMap(arr,target){
if(target===undefined) target=[];
for(var i=0;i<arr.length;i++){
if(arr[i] && arr[i].constructor===Array){
flatMap(arr[i],target);
}else{
target.push(arr[i]);
}
}
return target;
}
var list=flatMap(arr);
console.log(list);
|