每日Lodash(四)_.flatten

122 阅读1分钟

_.flatten

这个函数的功能

减少一级array嵌套深度。

源码

//flatten.js
function flatten(array) {
  const length = array == null ? 0 : array.length
  return length ? baseFlatten(array, 1) : []
}
//baseFlatten.js
function baseFlatten(array, depth, predicate, isStrict, result) {
  predicate || (predicate = isFlattenable)
  result || (result = [])

  if (array == null) {
    return result
  }

  for (const value of array) {
    if (depth > 0 && predicate(value)) {
      if (depth > 1) {
        // Recursively flatten arrays (susceptible to call stack limits).
        baseFlatten(value, depth - 1, predicate, isStrict, result)
      } else {
        result.push(...value)
      }
    } else if (!isStrict) {
      result[result.length] = value
    }
  }
  return result
}

解析

首先flatten主要通过检查传入的数组的长度,如果数组是null或者是undefined的话就会返回一个空数组,而如果传入非数组的值,并没有在这里进行判断,而是通过baseFlatten这个函数进行判断,并且主要将数组扁平化的逻辑都在这个函数里面。

接下来我们观察baseFlatten这个函数。因为我们传入的值,其实只有arraydepth,所以其他值都是初始值,我们并不用太关心。predicate其实初始化为一个函数,这个函数主要的功能就是检查传入的值是否可以被展平,可以就返回true 否则返回false.

当传入的值都是合法的时候就会进入下面的循环:

for (const value of array) {
    if (depth > 0 && predicate(value)) {
      if (depth > 1) {
        // Recursively flatten arrays (susceptible to call stack limits).
        baseFlatten(value, depth - 1, predicate, isStrict, result)
      } else {
        result.push(...value)
      }
    } else if (!isStrict) {
      result[result.length] = value
    }
  }

可以看到,它通过for...of遍历数组,如果我们展开的层级大于0并且合法就会进入下一级判断,接下来会判断层级是否大于1,如果大于1它就会递归调用,如果等于1,那么挥发这个value展开一层,并且放入result中。这样就会展开一层。