成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

展示JS前端面試數(shù)組扁平化手寫flat函數(shù)

3403771864 / 484人閱讀

  我們現(xiàn)在來說說怎么寫一下數(shù)組扁平化flat(),怎么樣?簡單說題目就是數(shù)組扁平化(也可以叫做手動封裝flat()方法),如何寫好那?

  按照不同的星級進行打分: 五星打分制

  滿分: ?????

  題目實現(xiàn)扁平化的方法 封裝 flatten

  題目描述:

  有多級嵌套數(shù)組 :[1, [2, [3, [4, 5]]], 6]將其扁平化處理 輸出:[1,2,3,4,5,6]

  什么是扁平化

  定義 : 扁平化就是將多維數(shù)組變成一維數(shù)組,不存在數(shù)組的嵌套

  1. ES6 flat

  flat(depth)方法會按照一個可指定的深度遞歸遍歷數(shù)組,并將所有元素與遍歷到的子數(shù)組中的元素合并為一個新數(shù)組返回。

  參數(shù):

  depth(可選) 指定要提取嵌套數(shù)組的結構深度,默認值為 1

  返回值:

  返回一個新數(shù)組,包含數(shù)組與提取嵌套數(shù)組的所有元素的新數(shù)組

  使用Infinity,可展開任意深度的嵌套數(shù)組

  封裝思路: 使用 es6 自帶 API 處理 

 const arr = [1, [2, [3, [4, 5]]], 6]
  function flatten(params) {
  return params.flat(Infinity)
  }
  console.log(flatten(arr));
  // 輸出: [1,2,3,4,5,6]

  得分 :?

  直接使用自帶的方法可以很快的實現(xiàn),但這個不是合適的!

  2. toString

  如果數(shù)組的項全為數(shù)字,可以使用join(),toString()可以利用數(shù)組toString() 轉為字符串 

 function flatten(arr) {
  return arr.toString().split(',').map(item =>parseFloat(item))
  }
  console.log(flatten(arr));
  // 輸出:[ 1, 2, 3, 4, 5, 6 ]

  得分 :? (并不是要考你的數(shù)組的方法調(diào)用)

  3. 使用正則替換

  看到嵌套的數(shù)組,如果在字符串的角度上看就是多了很多[和],如果把它們替換就可以實現(xiàn)簡單的扁平化

  function flatten (arr) {
  console.log('JSON.stringify(arr)', typeof JSON.stringify(arr))
  let str= JSON.stringify(arr).replace(/(\[|\])/g, '');
  str = '[' + str + ']';
  arr = JSON.parse(str);
  return arr
  }
  console.log(flatten(arr))

  得分: ? (并不是要考你的數(shù)組的方法調(diào)用)

  4. 循環(huán)遞歸

  4.1 循環(huán) + concat + push

  當只有一層嵌套數(shù)組使用push的方式扁平化

  [1, [2, 3,4,5,6]]


  let result = [];
  for (let i = 0; i < arr2.length; i++) {
  result = result.concat((arr2[i]));
  }
  console.log(result);
  [ 1, 2, 3, 4, 5, 6 ]

  如果有多層嵌套的數(shù)組就需要使用遞歸的思想:

  思路

  循環(huán)判斷數(shù)組的每一項是否是數(shù)組: Array.isArray(arr[i])

  是數(shù)組就遞歸調(diào)用上面的扁平化一層的代碼 result = result.concat(flatten(arr[i]));

  不是數(shù)組,直接通過push添加到返回值數(shù)組

   function flatten(arr) {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
  if (Array.isArray(arr[i])) {
  result = result.concat(flatten(arr[i]));
  } else {
  result.push(arr[i])
  }
  }
  return result
  }
  console.log(flatten(arr));

  或者使用forEach立即執(zhí)行函數(shù)

 

 // 遞歸版本的反嵌套
  function flatten(array) {
  var flattend = [];
  (function flat(array) {
  array.forEach(function(el) {
  if (Array.isArray(el)) flat(el);
  else flattend.push(el);
  });
  })(array);
  return flattend;
  }

  當然循環(huán)可以更改成forEach循環(huán),for of ...等其他循環(huán),簡單的循環(huán)遞歸就能夠一樣的解決啦~

  得分:??? (能夠使用遞歸寫出數(shù)組扁平化,缺少控制層級關系)

  4.2 增加參數(shù)控制扁平化深度

  這個可以理解為手寫flat()方法啦~

   // forEach 遍歷數(shù)組會自動跳過空元素
  const eachFlat = (arr = [], depth = 1) => {
  const result = []; // 緩存遞歸結果
  // 開始遞歸
  (function flat(arr, depth) {
  // forEach 會自動去除數(shù)組空位
  arr.forEach((item) => {
  // 控制遞歸深度
  if (Array.isArray(item) && depth > 0) {
  // 遞歸數(shù)組
  flat(item, depth - 1)
  } else {
  // 緩存元素
  result.push(item)
  }
  })
  })(arr, depth)
  // 返回遞歸結果
  return result;
  }
  // for of 循環(huán)不能去除數(shù)組空位,需要手動去除
  const forFlat = (arr = [], depth = 1) => {
  const result = [];
  (function flat(arr, depth) {
  for (let item of arr) {
  if (Array.isArray(item) && depth > 0) {
  flat(item, depth - 1)
  } else {
  // 去除空元素,添加非 undefined 元素
  item !== void 0 && result.push(item);
  }
  }
  })(arr, depth)
  return result;

  }

  得分:???? (能夠使用遞歸寫出數(shù)組扁平化,可以通過參數(shù)控制層級關系)

  4.3 巧用 reduce

  reduce方法為數(shù)組中的每個元素按序執(zhí)行一個reducer函數(shù),每一次運行 reducer 會將先前元素的計算結構作為參數(shù)傳入,最后將其結果匯總為單個返回值

  參數(shù):

  callbackFn一個 reducer 函數(shù),包含四個參數(shù):

  previousVal :上一次調(diào)用callbackFn時的返回值,在第一次調(diào)用時,若指定了初始值initialValue,previousVal 的值就位 initialValue,否則初始值就是為數(shù)組的索引為 0 的元素

  currentVal:數(shù)組中正在處理的元素,在第一次調(diào)用時,若指定了初始值,其值則為數(shù)組索引為 0 的元素 array[0],否則為 array[1]

  currentIndex: 數(shù)組中正在處理的元素的索引,若指定了初始值 initialValue,則起始索引號為 0,否則從索引 1 起始

  array : 用于遍歷的數(shù)組

  initialValue(可選) : 作為第一次調(diào)用 callback 函數(shù)時參數(shù) previousValue 的值

  返回值: 使用 reducer 回調(diào)函數(shù)遍歷整個數(shù)組后的結果

  思路:

  當我們使用 reduce 來解析第一層數(shù)組,可以得到:

  const arr = [1, [[2, 3], 4],5]
  const result = arr.reduce((acc, val) => acc.concat(val), []);
  console.log(result);
  // 輸出: [1,[2,3],4,5]

  可以看出上面的代碼可以扁平化一層數(shù)組,對于多層級嵌套的數(shù)組, 這個時候就需要使用遞歸的思想來解決問題了,再次遍歷數(shù)組,發(fā)現(xiàn)數(shù)組元素任然是數(shù)組的時候,再次執(zhí)行上面扁平化

  手寫方法

  const arr = [1, [[2, 3], 4],5]
  function flatten (arr,deep=1) {
  return arr.reduce((acc,val) => acc.concat(Array.isArray(val)? flatten(val,deep-1):val),[])
  }
  console.log(arr, Infinity);
  // 輸出:[ 1, 2, 3, 4, 5, 6 ]

  得分:???? (能夠使用遞歸寫出數(shù)組扁平化,巧用reduce方法可加分)

  4.4 使用 Generator 函數(shù)

  GeneratorFunction是協(xié)程在 ES6 的實現(xiàn),最大特點就是可以交出函數(shù)的執(zhí)行權(即暫停執(zhí)行)。

  它不同于普通函數(shù),是可以暫停執(zhí)行的,所以函數(shù)名之前要加星號,以示區(qū)別。

  整個 Generator 函數(shù)就是一個封裝的異步任務,或者說是異步任務的容器。異步操作需要暫停的地方,都用 yield 語句注明。Generator 函數(shù)的執(zhí)行方法如下。

  構造器生成新的生成器函數(shù)

  function* flatten(array) {
  for (const item of array) {
  if (Array.isArray(item)) {
  yield* flatten(item);
  } else {
  yield item;
  }
  }
  }

  得分:??? (使用Generator 函數(shù) 進行遞歸)

  5. 使用堆棧 stack 避免遞歸

  遞歸循環(huán)都可通過維護一個堆結構來解決

  如果不使用遞歸數(shù)組來實現(xiàn)扁平化,可以使用堆棧來解決

  深度的控制比較低效,因為需要檢查每一個值的深度

  思路:

  把數(shù)組通過一個棧來維護

  當棧不為空的時候循環(huán)執(zhí)行處理

  pop()將棧尾出棧

  如果出棧的元素是數(shù)組,就將該元素解構后每一元素進行入棧操作

  出棧的元素不是數(shù)組就push進返回值res

  反轉恢復原數(shù)組的順序

  var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
  function flatten(arr) {
  const stack = [...arr];
  const res = [];
  while (stack.length) {
  // 使用 pop 從 stack 中取出并移除值
  const next = stack.pop();
  if (Array.isArray(next)) {
  // 使用 push 送回內(nèi)層數(shù)組中的元素,不會改動原始輸入
  stack.push(...next);
  } else {
  res.push(next);
  }
  }
  // 反轉恢復原數(shù)組的順序
  return res.reverse();
  }
  flatten(arr1);// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]

  得分:???? (使用數(shù)據(jù)結構棧的特性取代遞歸操作,減少時間復雜度)

  6.while 循環(huán)+ some方法

  some:方法測試數(shù)組中是不是至少有 1 個元素通過了被提供的函數(shù)測試。它返回的是一個 Boolean 類型的值。

  思路

  通過some來判斷數(shù)組中是否用數(shù)組,通過while不斷循環(huán)執(zhí)行判斷, 如果是數(shù)組的話可以使用 拓展運算符... ... 每次只能展開最外層的數(shù)組,加上contact來減少嵌套層數(shù),

 

 function flatten(arr) {
  while (arr.some(item=&gt; Array.isArray(item))) {
  console.log(...arr)
  arr = [].concat(...arr)
  console.log(arr)
  }
  return arr
  }
  console.log(flatten(arr));

  得分:???? (使用while循環(huán)取消遞歸操作, 巧用some操作進行判斷)

      全文內(nèi)容已講述完畢,歡迎大家后續(xù)關注更多精彩內(nèi)容。

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/128174.html

相關文章

  • 記錄一次搜狐面試(包括筆試題)

    摘要:協(xié)議主要是通過請求頭當中的一些字段來和服務器進行通信,從而采用不同的緩存策略。會緩存所有的結構,但是問題在于,一些頁面開始時進行的上報或者請求可能會被影響。 1.如何用一個div實現(xiàn)下圖 showImg(https://segmentfault.com/img/bVbm8Rf?w=133&h=134); css #demo{ width:120px; h...

    tianhang 評論0 收藏0
  • 記錄一次搜狐面試(包括筆試題)

    摘要:協(xié)議主要是通過請求頭當中的一些字段來和服務器進行通信,從而采用不同的緩存策略。會緩存所有的結構,但是問題在于,一些頁面開始時進行的上報或者請求可能會被影響。 1.如何用一個div實現(xiàn)下圖 showImg(https://segmentfault.com/img/bVbm8Rf?w=133&h=134); css #demo{ width:120px; h...

    bladefury 評論0 收藏0
  • 前端JS面試

    摘要:前端面試題精選函數(shù)實現(xiàn)應用首先什么是函數(shù),直譯記憶,緩存等意思,到了計算機層面就翻譯為緩存函數(shù),緩存函數(shù)就是把計算的結果,存在函數(shù)中,當再次調(diào)用的時候就可以直接調(diào)用。 前端面試題精選 1.memorize函數(shù)實現(xiàn)應用 首先什么是memorize函數(shù),memorize直譯:記憶,緩存等意思,到了計算機層面就翻譯為緩存函數(shù),緩存函數(shù)就是把計算的結果,存在函數(shù)中,當再次調(diào)用的時候就可以直接調(diào)...

    bawn 評論0 收藏0
  • JS數(shù)組的幾個不low操作(3)

    摘要:序列文章面試之函數(shù)面試之對象前言本文主要從應用來講數(shù)組的一些騷操作如一行代碼扁平化維數(shù)組數(shù)組去重求數(shù)組最大值數(shù)組求和排序?qū)ο蠛蛿?shù)組的轉化等上面這些應用場景你可以用一行代碼實現(xiàn)扁平化維數(shù)組終極篇是扁平數(shù)組的表示維度值為時維度為無限大開始篇實質(zhì) showImg(https://segmentfault.com/img/bVbpRMS?w=1858&h=1286); 序列文章 JS面試之函數(shù)...

    fish 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<