js數組拍平(數組扁平化)的七種方式

分析輸入輸出

//輸入
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
//輸出
[1,2,3,4,5,6,7,8,9,10,11,12]
複製代碼

方法一(遞歸)

下降N個維度數組

function flat(arr){
	if(Object.prototype.toString.call(arr) != "[object Array]"){return false};
	let res = [];
	for(var i=0;i<arr.length;i++){
		if(arr[i] instanceof Array){
			res = res.concat(flat(arr[i]))
		}else{
			res.push(arr[i])
		}
	}
	return res;
};
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
flat(arr);
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
複製代碼

注意:

  • 數組鏈接用concat,保證數組的原有維度不變
  • push會改變原始數據,而且沒有鋪平數組的功能,你傳什麼進去,就是什麼。會致使數組的維度發生變化,增長了數組的維度

方法二(擴展運算符)

...擴展運算符,只適合下降一個維度。app

function flat(arr){
	if(Object.prototype.toString.call(arr) != "[object Array]"){return false};
	let res=[];
    arr.map(item=>{
        if(item instanceof Array){
            res.push(...item);//展開數組[11,12] 爲11,12
        }else{
            res.push(item)
        }
    });
    return res;
};	
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
flat(arr);
//[1, 2, 3, 4, 5, Array(3), 9, 10, 11, 12]
複製代碼

方法三(遞歸+擴展運算符)

下降N個維度ui

function flat(arr){
	if(Object.prototype.toString.call(arr) != "[object Array]"){return false};
	let res=[];
    arr.map(item=>{
        if(item instanceof Array){
            res.push(...flat(item));
        }else{
            res.push(item)
        }
    });
    return res;
};	
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
flat(arr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
複製代碼

方法四(遞歸+reduce)

下降N個維度spa

function flat(arr){
	if(Object.prototype.toString.call(arr) != "[object Array]"){return false};
	
	let res = arr.reduce((prev,cur)=>{
	    return prev.concat(Array.isArray(cur) ? flat(cur) : cur)
	},[])
	return res;
};
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
flat(arr);

// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
複製代碼

reduce內部也可這麼寫prototype

[...a,...b] 其做用至關於a.concat(b),這種用法更加直觀明瞭code

if(!Array.isArray(cur)){
    return [...prev,cur];
}else{
    return [...prev,...flat(cur)]
}
複製代碼
reduce((prev,cur,index,arr)=>{},init)用法
  • 兩個參數,一個callback,一個初始值
  • 回調的四個參數分別爲,上一次 return的結果,當前項,當前索引,數組,還有初始值。
  • reduce實現什麼功能取決於回調內部作了什麼

方法五(toString+split)

toString可直接去除掉中括號遞歸

var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
var arr1 = arr.toString().split(',').map((val)=>{
            return parseInt(val)
});
console.log(arr1);
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

//思路
[1,2,[3,4,5,[6,7,8],9],10,[11,12]].toString().split(",")
// ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
[1,2,[3,4,5,[6,7,8],9],10,[11,12]].toString()
//"1,2,3,4,5,6,7,8,9,10,11,12"
複製代碼

方法六(原生的flat)

參數爲層數(默認一層)索引

[1,2,[3]].flat()
// [1, 2, 3]

[1,2,[3,[4]]].flat(2)
// [1, 2, 3, 4]

複製代碼

方法七(while+some+apply)

function flat(arr){
     while(arr.some(item => Array.isArray(item))){
        arr = [].concat.apply([],arr);
     }
     return arr;
}
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
flat(arr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
複製代碼

總結

  • 建議少使用遞歸
  • 建議使用toString直接幹掉中括號,獲得字符串,再轉爲數組
相關文章
相關標籤/搜索