解析lodash的 多维数组扁平化方法

429 阅读1分钟

lodash实现数组扁平化,有几个点, 判断当前数据是否可被扁平话,要么数据是数组,要么是arguments对象(类数组),要么数据的属性Symbol.isConcatSpreadable为true

1:递归 2: isFlattenable 3: isArguments 4: Symbol.isConcatSpreadable

const isObjectLike = (value) =>{
    return typeof value === 'object' && value !== null
}
/**
 * 检测传入方法的数据是arguments对象
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is arguments, else `false`.
 */

const isArguments = (value)=>{
    return isObjectLike(value) && Object.prototype.toString.call(value) === '[object Arguments]'
}

/**
 * 检测传入方法的数据是flattenable的
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
 */
const isFlattenable = (value) =>{
    return Array.isArray(value) || isArguments(value) || (value && value[Symbol.isConcatSpreadable])
}

/**
 * 
 *
 * @private
 * @param {*} array.
 * @returns {boolean} 返回多维数组长度
 */
let arrayLatitudeLength = (array)=>{
    return JSON.stringify(array).match(/\[/g).length;
}
const flatten = (array,depth,result)=>{
   result = result || [];
   if(array === null ) return result;
   // 先把多维数组,stringify化,然后正则匹配[字符,然后取length,相当于有多少个[,就有几纬数组。
   
   for(const value of array){
       if(depth > 0 && isFlattenable(value)){
           if(depth>1){
               flatten(value, depth -1, result)
           }else{
               result.push(...value)
           }
       }else{
           result[result.length] = value
       }
   }
   return result
}