數(shù)組扁平化概念
數(shù)組扁平化是指將一個(gè)多維數(shù)組變?yōu)橐痪S數(shù)組
實(shí)現(xiàn)
1. reduce
遍歷數(shù)組每一項(xiàng),若值為數(shù)組則遞歸遍歷挪略,否則concat磨确。
function flatten(arr) {
return arr.reduce((result, item)=> {
return result.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}
reduce是數(shù)組的一種方法,它接收一個(gè)函數(shù)作為累加器桶蝎,數(shù)組中的每個(gè)值(從左到右)開始縮減驻仅,最終計(jì)算為一個(gè)值。
reduce包含兩個(gè)參數(shù):回調(diào)函數(shù)登渣,傳給total的初始值
// 求數(shù)組的各項(xiàng)值相加的和:
arr.reduce((total, item)=> { // total為之前的計(jì)算結(jié)果噪服,item為數(shù)組的各項(xiàng)值
return total + item;
}, 0);
2. toString & split
調(diào)用數(shù)組的toString方法,將數(shù)組變?yōu)樽址缓笤儆胹plit分割還原為數(shù)組
function flatten(arr) {
return arr.toString().split(',').map(function(item) {
return Number(item);
})
}
因?yàn)閟plit分割后形成的數(shù)組的每一項(xiàng)值為字符串胜茧,所以需要用一個(gè)map方法遍歷數(shù)組將其每一項(xiàng)轉(zhuǎn)換為數(shù)值型
3. join & split
和上面的toString一樣粘优,join也可以將數(shù)組轉(zhuǎn)換為字符串
function flatten(arr) {
return arr.join(',').split(',').map(function(item) {
return parseInt(item);
})
}
4. 遞歸
遞歸的遍歷每一項(xiàng)仇味,若為數(shù)組則繼續(xù)遍歷,否則concat
function flatten(arr) {
var res = [];
arr.map(item => {
if(Array.isArray(item)) {
res = res.concat(flatten(item));
} else {
res.push(item);
}
});
return res;
}
5. 擴(kuò)展運(yùn)算符
es6的擴(kuò)展運(yùn)算符能將二維數(shù)組變?yōu)橐痪S
[].concat(...[1, 2, 3, [4, 5]]); // [1, 2, 3, 4, 5]
根據(jù)這個(gè)結(jié)果我們可以做一個(gè)遍歷雹顺,若arr中含有數(shù)組則使用一次擴(kuò)展運(yùn)算符丹墨,直至沒(méi)有為止。
function flatten(arr) {
while(arr.some(item=>Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
6. es6數(shù)組flat方法
數(shù)組的成員有時(shí)還是數(shù)組嬉愧,Array.prototype.flat()用于將嵌套的數(shù)組“拉平”贩挣。該方法返回一個(gè)新數(shù)組,對(duì)原數(shù)組沒(méi)有任何影響
console.log([1, 2, ['a', 'c']].flat()); // [1, 2, "a", "c"]
flat()默認(rèn)只會(huì)拉平一層没酣,如果想要拉平多層嵌套數(shù)組王财,可以將flat的方法的參數(shù)寫成一個(gè)整數(shù),表示想要拉平的層數(shù)裕便,默認(rèn)為1
console.log([1, 2, [3, 4, [5]]].flat());//[1, 2, 3, 4, [5]]
console.log([1, 2, [3, 4, [5]]].flat(2));//[1, 2, 3, 4, 5]
如果不管有多少層嵌套搪搏,都要轉(zhuǎn)成一堆數(shù)組,可以用Infinity關(guān)鍵字作為參數(shù)
console.log([1, [2, [3, [4, 5, ['a']]]]].flat(Infinity)); // [1, 2, 3, 4, 5, "a"]
需要注意的是闪金,如果原數(shù)組中有空位疯溺,flat()方法會(huì)跳過(guò)空位
flatMap()方法對(duì)原數(shù)組的每個(gè)成員執(zhí)行一個(gè)函數(shù)(相當(dāng)于執(zhí)行Array.prototype.map()),然后對(duì)返回值組成的數(shù)組執(zhí)行flat()方法哎垦,該方法返回一個(gè)新數(shù)組囱嫩,不改變?cè)瓟?shù)組。
console.log([1, 2, 3].flatMap((x) => [x, x * x]));//[1, 1, 2, 4, 3, 9]
flatMap()只能展開一層數(shù)組
console.log([1, 2, 3].flatMap((x) => [
[x, x * x]
])); //[[1, 1], [2, 4], [3, 9]]
flatMap()方法的參數(shù)是一個(gè)遍歷函數(shù)漏设,該函數(shù)可以接受三個(gè)參數(shù)墨闲,分別是當(dāng)前數(shù)組成員,當(dāng)前數(shù)組成員位置(從0開始)郑口,原數(shù)組鸳碧。而flatMap()方法還可以有第二個(gè)參數(shù),用來(lái)綁定遍歷函數(shù)里面的this.
總結(jié)
核心也只有一個(gè):
遍歷數(shù)組arr犬性,若arr[i]為數(shù)組則遞歸遍歷瞻离,直至arr[i]不為數(shù)組然后與之前的結(jié)果concat。
數(shù)組的空位
數(shù)組的空位值就是數(shù)組的某一個(gè)位置沒(méi)有任何值乒裆。比如套利,Array構(gòu)造函數(shù)返回的數(shù)組都是空位
console.log(Array(3)); // [, , ,]
注意『姿#空位不是undefined肉迫,一個(gè)位置的值等于undefined,依然是有值的稿黄,空位是指沒(méi)有任何值喊衫。
由于數(shù)組的眾多方法對(duì)空位的處理規(guī)則非常不統(tǒng)一,所以建議避免出現(xiàn)空位