一道关于 ARRAY 深度展开的面试题

今天面试的时候,考官出了这么一个题,写一个函数,输入a = [1,[2,3,[4,5,6]]],输出a = [1,2,3,4,5,6]。当时我脑子有点短路,作了很久,给出了个不太符合要求的答案以下git

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
}

回家后稍微完善了下,符合了考官输入输出的要求了(不过也晚了)github

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)
}

而后跟朋友聊天问问有啥简单的方法,朋友给了一个挺符合这个题的简单方法相似以下面试

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

不过这个答案只适用于这道题,若是不是全数字的就不行了。因而在GitHub上搜索array flatten,看了看排名前三的源码,发现有好多不一样的写法,好比npm

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

也有这么写的app

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

写法各不相同,还有好多看似相似,但细节上不同的,因此关键就看性能了,好在arr-flattenarray-flatten中就都有benchmark,进行了各类比较函数

arr-flatten这个项目中,在各类不一样的、能够在 npm 上搜到的array flatten实现方法之间进行了比较,最后的结论是array-flatten执行的效率最高性能

array-flatten项目里的benchmark主要是本身源码中细节不一样的写法之间的差别,最后得出的最佳实践以下测试

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
}

这套代码思路与我给出的答案是同样的,但因为细节上的不一样,致使用benchmark测试,执行效率比我写的那个快了约20%spa

相关文章
相关标签/搜索