es6删除数组某一项_精学手撕系列——数组扁平化
參考文章:面試官連環追問:數組拍平(扁平化) flat 方法實現
編者薦語:
在前端面試中,手寫flat是非常基礎的面試題,通常出現在筆試或者第一輪面試中,主要考察面試者基本的手寫代碼能力和JavaScript的基本功。
今天就帶大家從0了解flat特性到手寫實現flat,再到接住面試官的連環追問中重新學習一遍數組扁平化flat方法
Array.prototype.flat()
一段代碼總結Array.prototype.flat()特性
注:數組拍平方法 Array.prototype.flat() 也叫數組扁平化、數組拉平、數組降維。
let?arr?=?[12,?23,?[34,?56,?[78,?90,?100,?[110,?120,?130]]]];console.log(arr.flat());?
//?[?12,?23,?34,?56,?[?78,?90,?100,?[?110,?120,?130?]?]?]
console.log(arr.flat(2));
//?[?12,?23,?34,?56,?78,?90,?100,?[?110,?120,?130?]?]
console.log(arr.flat(Infinity));
//?[12,?23,?34,?56,?78,?90,?100,?110,?120,?130]
console.log(arr.flat(0));
//?[12,?23,?[34,?56,?[78,?90,?100,?[110,?120,?130]]]];
console.log(arr.flat(-10));
//?[12,?23,?[34,?56,?[78,?90,?100,?[110,?120,?130]]]];
let?arr2?=?[12,?23,?[34,?56,?,]]
console.log(arr.flat());
//?[?12,?23,?34,?56?]
Array.prototype.flat() 特性總結
Array.prototype.flat() 用于將嵌套的數組“拉平”,變成一維的數組。該方法返回一個新數組,對原數據沒有影響。
不傳參數時,默認“拉平”一層,可以傳入一個整數,表示想要“拉平”的層數。
傳入 <=0 的整數將返回原數組,不“拉平”
Infinity 關鍵字作為參數時,無論多少層嵌套,都會轉為一維數組
如果原數組有空位,Array.prototype.flat() 會跳過空位。
面試官 N 連問:
第一問:下面數組如何實現扁平化?
let?arr?=?[??[1,?2,?2],
??[3,?4,?5,?5],
??[6,?7,?8,?9,?[11,?12,?[12,?13,?[14]]]],?10
];
小伙伴首先想到的肯定是用 ES6 的Array.prototype.flat方法呀
方法一:flat
arr?=?arr.flat(2);//?[?1,?2,?2,?3,?4,?5,?5,?6,?7,?8,?9,?11,?12,?[?12,?13,?[?14?]?],?10?]
當flat中傳入數字時,是扁平對應的層數,顯然這不是我們想要的,因為它還沒有完全展開。
這是,flat函數中就為我們提供了一個參數Infinity,譯為無窮的意思。
arr?=?arr.flat(Infinity);/*?[
???1,??2,??2,?3,??4,??5,??5,
???6,??7,??8,?9,?11,?12,?12,
??13,?14,?10
]?*/
當我們不知道數組中嵌套了幾維數組時,我們可以用Infinity這個參數,幫我們全部展開。
第二問:還有其它的辦法嗎?因為它們在高版本瀏覽器并不兼容
方法二:轉換為字符串,再把字符串對象用,轉換成數組
可以先把多維數組先轉換為字符串,再基于,分隔符將字符串對象分割成字符串數組
toString() 扁平化數組
arr?=?arr.toString();//?"1,2,2,3,4,5,5,6,7,8,9,11,12,12,13,14,10"
arr?=?arr.toString().split(',');
//?["1",?"2",?"2",?"3",?"4",?"5",?"5",?"6",?"7",?"8",?"9",?"11",?"12",?"12",?"13",?"14",?"10"]
arr?=?arr.toString().split(',').map(item?=>?parseFloat(item));
//?[1,?2,?2,?3,?4,?5,?5,?6,?7,?8,?9,?11,?12,?12,?13,?14,?10]
除了上面的方法還有什么方法轉換為字符串呢?
JSON.stringify()扁平化數組
arr?=?JSON.stringify(arr);//?"[[1,2,2],[3,4,5,5],[6,7,8,9,[11,12,[12,13,[14]]]],10]"
arr?=?JSON.stringify(arr).replace(/(\[|\])/g,?'');
//?"1,2,2,3,4,5,5,6,7,8,9,11,12,12,13,14,10"
arr?=?JSON.stringify(arr).replace(/(\[|\])/g,?'').split(',').map(item=>parseFloat(item));
//?[1,?2,?2,?3,?4,?5,?5,?6,?7,?8,?9,?11,?12,?12,?13,?14,?10]
方法三:循環驗證是否為數組
基于數組的some方法,只要數組里面有一項元素是數組就繼續循環,扁平數組
核心:[].concat(...arr)
whilte?(arr.some(item?=>?Array.isArray(item)))?{?arr?=?[].concat(...arr);
}
console.log(arr);?//?[1,?2,?2,?3,?4,?5,?5,?6,?7,?8,?9,?11,?12,?12,?13,?14,?10]
第三問:能自己實現一個 flat 扁平化嗎?
先回答:能!!再跟著我分析思路:
如何實現呢,其實思路非常簡單:在數組中找到是數組類型的元素,然后將他們展開,這就是flat方法的關鍵思路
實現思路:
- 循環數組里的每一個元素
- 判斷該元素是否為數組
- 是數組的話,繼續循環遍歷這個元素——數組
- 不是數組的話,把元素添加到新的數組中
實現流程:
- 數組的話,繼續循環
- 非數組的話,添加到新數組中
ES5 實現 flat 扁平化方法
let?arr?=?[????[1,?2,?2],
????[3,?4,?5,?5],
????[6,?7,?8,?9,?[11,?12,?[12,?13,?[14]]]],?10
];
function?myFlat()?{
??_this?=?this;?//?保存 this:arr
??let?newArr?=?[];
??//?循環arr中的每一項,把不是數組的元素存儲到?newArr中
??let?cycleArray?=?(arr)?=>?{
????for?(let?i=0;?i??????let?item?=?arr[i];
??????if?(Array.isArray(item))?{?//?元素是數組的話,繼續循環遍歷該數組
????????cycleArray(item);
????????continue;
??????}?else{
????????newArr.push(item);?//?不是數組的話,直接添加到新數組中
??????}
????}
??}
??cycleArray(_this);?//?循環數組里的每個元素
??return?newArr;?//?返回新的數組對象
}
Array.prototype.myFlat?=?myFlat;
arr?=?arr.myFlat();?//?[1,?2,?2,?3,?4,?5,?5,?6,?7,?8,?9,?11,?12,?12,?13,?14,?10]
ES6 實現 flat 扁平化方法
const?myFlat?=?(arr)?=>?{??let?newArr?=?[];
??let?cycleArray?=?(arr)?=>?{
????for(let?i?=?0;?i???????let?item?=?arr[i];
??????if?(Array.isArray(item))?{
????????cycleArray(item);
????????continue;
??????}?else?{
????????newArr.push(item);
??????}
????}
??}
??cycleArray(arr);
??return?newArr;
}
myFlat(arr);?//?[1,?2,?2,?3,?4,?5,?5,?6,?7,?8,?9,?11,?12,?12,?13,?14,?10]
第四問:請使用reduce實現flat函數
相信很多面試官都會指定讓面試者用reduce方法實現flat函數
其實思路也是一樣的,在實現之前,先來看一下
它的核心:[].concat(...arr)
但是它只能將數組元素展開一層,來看下面例子:
let?arr2?=?[12,?23,?[34,?56,?[78,?90,?100]]];[].concat(...arr2);
//?[?12,?23,?34,?56,?[?78,?90,?100?]?]
細心的同學可以發現[].concat(...arr)只能展開一層數組元素,當有更深層次的,是無法展開的
接下來,我們來看看用reduce怎么實現?
let?arr?=?[12,?23,?[34,?56,?[78,?90,?100,?[110,?120,?130,?140]]]];const?myFlat?=?arr?=>?{
??return?arr.reduce((pre,?cur)?=>?{
????return?pre.concat(cur);
??},?[]);
};
console.log(myFlat(arr));
//?[?12,?23,?34,?56,?[?78,?90,?100,?[?110,?120,?130,?140?]?]?]
const?myFlat?=?arr?=>?{
??return?arr.reduce((pre,?cur)?=>?{
????return?pre.concat(Array.isArray(cur)???myFlat(cur)?:?cur);
??},?[]);
};
console.log(myFlat(arr));
//?[12,?23,?34,?56,?78,?90,?100,?110,?120,?130,?140]
上面代碼中的Array.isArray(cur)和myFlat(cur)實際就好比與遍歷數組每一項,看它是不是數組元素,
如果是的話,則繼續遞歸遍歷,不是的話直接數組合并非數組元素。
第五問:使用棧的思想實現flat函數
棧思想: 后進先出的數據結構
實現思路:
不斷獲取并刪除棧中最后一個元素A,判斷A是否為數組元素,直到棧內元素為空,全部添加到newArr
- 是數組,則push到棧中,繼續循環棧內元素,直到棧為空
- 不是數組,則unshift添加到newArr中
function?flat(arr)?{
??const?newArr?=?[];
??const?stack?=?[].concat(arr);??//?將數組元素拷貝至棧,直接賦值會改變原數組
??//如果棧不為空,則循環遍歷
??while?(stack.length?!==?0)?{
????const?val?=?stack.pop();?//?刪除數組最后一個元素,并獲取它
????if?(Array.isArray(val))?{
??????stack.push(...val);?//?如果是數組再次入棧,并且展開了一層
????}?else?{
??????newArr.unshift(val);?//?如果不是數組就將其取出來放入結果數組中
????}
??}
??return?newArr;
}
let?arr?=?[12,?23,?[34,?56,?[78,?90,?100,?[110,?120,?130,?140]]]];
console.log(flat(arr));
//?[12,?23,?34,?56,?78,?90,?100,?110,?120,?130,?140]
本文總結
看完這篇文章的同學,可以在面試的時候分類,分思想給面試官描述,可以先說我用哪幾種思想實現過,它們的寫法又分別有什么不同。
最后希望這篇文章可以幫助到大家,感謝閱讀。
看完三件事?
如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
總結
以上是生活随笔為你收集整理的es6删除数组某一项_精学手撕系列——数组扁平化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql scws_apache+my
- 下一篇: 朗读评价语言集锦_评语大全之朗诵评语艺术