Hello, 大噶好, 小葵花媽媽課堂開課啦。。。。。。數組
咱們平常工做中拿到的數據不多是隻有一維的平面數組, 百分之99.99 是數組裏嵌套數組再套數組的n維數組 .............................函數
這種讓人想問候它xx的多維數組咱們怎麼把它變成一維數組, 也就是隻有一箇中括號 的數組 呢 ? spa
接下來咱們 一步一步來實現它 , Follow me code
講降維以前, 咱們先來回顧一下 數組 有哪些 方法 ? blog
給同窗們一秒鐘時間思考。。。排序
請同窗們 舉手回答 。。。。 遞歸
OK 爲了方便記憶,咱們能夠把數組的方法分紅兩類 :索引
1 不改變原數組的方法unicode
2 改變原數組的方法字符串
先說會改變原數組的方法 :
sort() 數組的排序方法 , 能夠傳一個回調函數, 不傳參數默認按照字符串的unicode碼位點排序
因此不傳參 的話 10 是 小於 2 的 。。。。先比第一位 1 < 2 ,只有第一位相等纔會比第二位,
因此 10 < 2,回調函數接受兩個參數, 能夠在回調函數中定義排序的規則, 執行後返回改變後的原數組
reverse() 數組逆序 執行後返回改變後的原數組
pop() 彈出數組的最後一個元素 執行後返回彈出的變量
shift() 彈出數組的第一個元素 執行後返回彈出的變量
push() 在數組的末尾加(可加多個元素) 執行後返回改變後的原數組的length
unshift() 在數組的頭部加(可加多個元素) 執行後返回改變後的原數組的length
splice(start, deleteCount, new可選) 用於刪除指定區域的元素, 並能夠在刪除的區域添加新的元素
new能夠是多個新元素
執行後返回被刪除的元素
copyWithin(start, end可選, stop可選) 複製 index = end 的元素 並 替換 掉 index = start 的元素 ,
stop 表示 在第幾位 中止複製( IE 11 及更早版本不支持 copyWithin() 方法),
執行後返回改變後的原數組
fill(value, start可選, end可選) 把數組的start 位 到 end 位 的元素 都用 value 替換掉 ,
只傳value,數組的全部元素都用value替換,
執行後返回改變後的原數組
不改變原數組的方法:
concat() 數組合並, 能夠傳數組也能夠傳參數列表 , 返回一個合併後的新數組
若是合併的數組裏面有引用值, 新數組中的引用值的地址和原來同樣,
改變其中一個,另外一個也會發生改變, 因此並不能用來深拷貝。
(下一期咱們會來討論一下 深淺拷貝 )
includes(value, start可選) 從start處日後查找 value 是否在數組中, 返回一個布爾值
indexOf(value, start可選) 從start 開始 日後查找 value, 返回找到的第一個值的索引,
沒找到返回-1
lastIndexOf(value, start可選) 從索引爲start的元素開始往前查找,返回找到的第一個值的索引,
沒找到返回-1
join(string可選) 把數組裏的每一項用string裏的符號拼接成一個字符串,
不傳參數用逗號拼接成一個字符串
find(callback) 按照callback裏的篩選條件返回第一個符合條件的元素
findIndex(callback) 按照callback裏的篩選條件返回第一個符合條件的元素的索引
toString() 把數組轉換成字符串 == > join() ;
slice(start可選, end可選) 從數組索引爲start處開始複製到索引爲(end - 1)的元素
返回一個由複製出來的元素組成的數組,
不傳參數複製整個數組,
注意:不傳參複製的數組內部若是有引用值的話,複製後引用值
指向同一個地址, 不能實現深拷貝
數組還有不少遍歷的方法我就不一一列出來了,
咱們開始進入正題 。。。。。。
和 扁平化 數組有關的方法 :
1 flat(deep可選) deep降維深度 ; deep = 0 不降維
deep 等於幾 就降幾維,
不傳deep 降一維
2 flatMap(callback) callback 裏能夠操做數組, 只能降一維
上例子:
1 var a = [1, 2, 3, 4, 5, [2,3,4,[6,10]]]; // 3維數組 2 3 var b = a.flat(2); // 參數爲 維數 減一 4 console.log(b); // b = [1, 2, 3, 4, 5, 2, 3, 4, 6, 10] 5 6 var c = a.flatMap( (value, index, array) => { //只能用於2維數組的降維 7 return value + 1; 8 }); 9 console.log(c); // c = [2, 3, 4, 5, 6, "2,3,4,6,101"]
須要注意的是:
1 flat 只能用於已知維度的數組降維
2 flatMap 若是數組內有引用值 , 引用值會先調用toString()方法轉換成字符串再進行計算
對於未知維度的數組, 咱們須要 借用 reduce() 方法
reduce(callback, init可選) 俗稱累加器 callback裏寫累加規則, init 爲初始值
// 多維度降維使用遞歸 deepFlat = (arr) => { return arr.reduce((a, b) => { return Array.isArray(b) ? [...a, ...deepFlat(b)] : [...a, b] }, []) };
分析 給一個初始值 [] , 第一次 a = 初始值[] , b是數組的第一位 , 判斷b是不是數組,
若是是數組,遞歸繼續降維,降維的結果和a 合併
若是不是數組, 直接和a合併,
合併的結果做爲下一次初始值,
第二次 a 爲 上一次獲得的初始值, b 爲數組的第二位, 以此類推 。。。。。。。
這樣寫有個小問題, 若是第一次傳進去的不是數組的話會報錯 !
Uncaught TypeError: arr.reduce is not a function
因此若是不想加額外的判斷的話,還能夠這樣寫
const flattenDeep = (arr) => { return Array.isArray(arr) ? arr.reduce((a, b) => { return [...a, ...flattenDeep(b)] }, []) : [arr] };
再分析 先判斷傳進來的實參arr是不是數組, 若是不是的話直接返回【arr】,
若是是的話 再 調用 reduce()方法 進行遞歸降維 ,
更騷的寫法
const flattenDeep = (arr) => Array.isArray(arr) ? arr.reduce((a, b) => [...a, ...flattenDeep(b)], []) : [arr];
把 大括號 和 return 都 去掉 , 一句話 搞定 !!!