面試官:給我手寫一個數組扁平化吧,我不要flat。web
我:。。。💥面試
數組扁平化? 聽起來好像灰常的好大上?真的嗎?數組
那數組扁平化究竟是什麼?怎麼實現呢?markdown
數組的扁平化處理,其實就是多維數組轉化爲一維數組。以下,將上面這個數組轉化爲下面的數組函數
那怎麼去實現呢?彆着急。咱們一個一個說。ui
ary = arr.flat(Infinity)
console.log([1, [2, 3, [4, 5]]].flat(Infinity))
複製代碼
Array.protype.flat()用於將數組「拉平」,變成一維數組,返回一個新數組。flat()默認只會拉平一層,flat(n)拉平n層,Infinity無限次。好用歸好用,但效率咱們就內心明白,這也是咱們面試官最不想聽到的答案了。url
//第一種處理
ary = str.replace(/(\[|\])/g, '');
//第二種處理
str = str.replace(/(\[|\]))/g, '');
str = '[' + str + ']';
ary = JSON.parse(str);
複製代碼
let arr = [1, [2, [3, 4]]];
function flattern(arr,result =[]) {
for(let i = 0; i < arr.length; i++) {
if(Array.isArray(arr[i])) {
flattern(arr[i], result)
} else {
result.push(arr[i])
}
}
return result;
}
console.log(flattern(arr));
複製代碼
這也是我當時面試想到最簡單的解決方案,思路很簡單,經過遍歷最外層數組的每個元素,看看是否仍是數組,若是是的話,繼續遞歸執行,不是的話,放到最後的結果數組當中spa
let arr = [1, [2, [3, 4]]];
function flatten(arr) {
return arr.reduce(function(prev, next){
return prev.concat(Array.isArray(next) ? flatten(next) : next)
}, [])
}
console.log(flatten(arr))
//reduce搭配擴展運算符
const flatten = (array) => array.reduce((acc,cur)=>
(Array.isArray(cur)?[...acc,...flatten(cur)]:[...acc,cur]),[])
複製代碼
提到數組的方法,就會聯想到很是經常使用的2個高階函數map和reduce。其實思路上和上面遞歸的很類似。3d
const arr = [1,2,[3,4,5,[6,7],8],9,10,[11,[12,13]]];
const flatten = (arr) => {
while(arr.some(item=>Array.isArray(item))){
arr=[].concat(...arr);
}
return arr;
}
console.log(flatten(arr)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
複製代碼
因爲擴展運算符一次只能展開一層數組code
var arr = [1, [2, [3, 4]]];
console.log([].concat(...arr)); // [1, 2, [3, 4]]
複製代碼
所以考慮只要數組中還有數組,就使用擴展運算符展開一次。
function flatten(arr){
//arr.join(',').split(','); join也能夠實現
return arr.toString().split(',').map(function(item){
return +item; //+將字符轉換爲數字
})
}
複製代碼
若是數組的元素都是數字,能夠考慮使用 toString 方法,由於:toString會將數組中的數以逗號形式結合起來。toString以後再split轉成數組,並將其轉換回數字。因此這種場景只適用於數組內所有是數字的狀況,由於中間是所有轉換爲字符串了。