一道關(guān)于 ARRAY 深度展開(kāi)的面試題

昨天面試的時(shí)候,考官出了這么一個(gè)題,寫一個(gè)函數(shù),輸入a = [1,[2,3,[4,5,6]]],輸出a = [1,2,3,4,5,6]。當(dāng)時(shí)我腦子有點(diǎn)短路,做了好久,給出了個(gè)不太符合要求的答案如下

var a = [1,[2,3,[4,5,6]]]
var arr = []
function merge(a) {
  for(var i = 0; i < a.length; i++){
    if(Array.isArray(a[i])){
      merge(a[i])
    } else {
      arr.push(a[i])
    }
  }
  return arr
}

回家后稍微完善了下,符合了考官輸入輸出的要求了(不過(guò)也晚了)

function flatten(a) {
  if (!Array.isArray(a)) return

  var arr = []

  return (function merge(a) {
    for(var i = 0, l = a.length; i < l; i++){
      if(Array.isArray(a[i])){
        merge(a[i])
      } else {
        arr.push(a[i])
      }
    }
    return arr
  })(a)
}

然后跟朋友聊天問(wèn)問(wèn)有啥簡(jiǎn)單的方法,朋友給了一個(gè)挺符合這個(gè)題的簡(jiǎn)單方法類似如下

const flatten = (arr) => arr.toString().split(',').map(v => Number(v))

不過(guò)這個(gè)答案只適用于這道題,如果不是全數(shù)字的就不行了。于是在GitHub上搜索array flatten,看了看排名前三的源碼,發(fā)現(xiàn)有好多不同的寫法,比如

function flatten() {
  var args = Array.from(arguments)
  do {
    args = [].concat.apply([], args)
  } while (args.some(Array.isArray))
  return args
}

也有這么寫的

function flatten (array) {
  var result = Array.prototype.concat.apply([], array)
  if (result.length === array.length) {
    return result
  }
  return flatten(result)
}

寫法各不相同,還有好多看似類似,但細(xì)節(jié)上不一樣的,所以關(guān)鍵就看性能了,好在arr-flattenarray-flatten中就都有benchmark,進(jìn)行了各種比較

arr-flatten這個(gè)項(xiàng)目中,在各種不同的、可以在 npm 上搜到的array flatten實(shí)現(xiàn)方法之間進(jìn)行了比較,最后的結(jié)論是array-flatten執(zhí)行的效率最高

array-flatten項(xiàng)目里的benchmark主要是自己源碼中細(xì)節(jié)不同的寫法之間的差異,最后得出的最佳實(shí)踐如下

function flatten (array) {
  if (!Array.isArray(array)) {
    throw new TypeError('Expected value to be an array')
  }
  return flattenFrom(array)
}

function flattenFrom (array) {
  return flattenDown(array, [])
}

function flattenDown (array, result) {
  for (var i = 0; i < array.length; i++) {
    var value = array[i]

    if (Array.isArray(value)) {
      flattenDown(value, result)
    } else {
      result.push(value)
    }
  }

  return result
}

這套代碼思路與我給出的答案是一樣的,但由于細(xì)節(jié)上的不同,導(dǎo)致用benchmark測(cè)試,執(zhí)行效率比我寫的那個(gè)快了約20%

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問(wèn)題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,769評(píng)論 0 33
  • <a name='html'>HTML</a> Doctype作用?標(biāo)準(zhǔn)模式與兼容模式各有什么區(qū)別? (1)、<...
    clark124閱讀 3,551評(píng)論 1 19
  • 數(shù)組是一種可變的、可索引的數(shù)據(jù)集合。在Scala中用Array[T]的形式來(lái)表示Java中的數(shù)組形式 T[]。 v...
    時(shí)待吾閱讀 967評(píng)論 0 0
  • 今天是兒童節(jié),可我都三十了,已經(jīng)不算兒童了,對(duì)于這樣的節(jié)日確實(shí)沒(méi)什么好說(shuō)的。昨天聽(tīng)老梁的專題又講到了日本的癡文化~...
    韌針小郭閱讀 341評(píng)論 0 0
  • 10.2 一個(gè)巧合,一段故事 我們?cè)J(rèn)為只是彼此的過(guò)客 無(wú)數(shù)次的擦肩而過(guò),我卻沒(méi)有曾為你停下我的跳步 我們?cè)钤?..
    YC一辰閱讀 258評(píng)論 1 0