手写Lodash-get方法

913 阅读1分钟
    // 传入数组路径
    function getByArrayPath(obj = {}, pathArr = []) {
      let res = obj

      pathArr.some((key) => {
        try {
          res = res[key]
        } catch(err) {
          console.error(err)
          return true
        }
      })

      return res
    }
    
    // 传入字符串路径
    function getByStringPath(obj = {}, pathStr = '') {
      // pathStr = 'data[0].info.test[0][0]'
      // 根据 "." 来进行初步分组 ---- ['data[0]', 'info', 'test[0][0]']
      let tempArr = pathStr.split('.')
      const pathArr = []
      
      // 开始解析分组中的下标
      tempArr.forEach((str) => {
        // str = test[0][0]
        // 匹配下标的正则
        const arrPathRule = /\[[0-9]+\]\B/g
        const arrPathList = str.match(arrPathRule) || [] // arrPathList =  ['[0]', '[0]']
        const allPathArr = [] // 下标数组
        
        // 如果路径里有数组下标
        if(arrPathList.length) {
          arrPathList.forEach((fullPath) => {
             // fullPath = '[0]'
             // 去除中括号
             const path = fullPath.replace(/[\[\]]/g, '')
             allPathArr.push(path)
          }) 
          
          // 清除下标字符串 ---- str = 'test'
          str = str.replace(arrPathRule, '')
        }
        
        // str = 'test'
        // allPathArr = ['0', '0']
        // 将解析完成的下标和原有路径推入路径数组
        pathArr.push(str, ...allPathArr)
      })
      
      // pathArr = ['data', '0', 'info', 'test', '0', '0']
      // 将解析完成的路径数组放入数组查询方法
      return getByArrayPath(obj, pathArr)
    }
    
    const res = getByStringPath({
      data: [
        {
          info: {
            test: [
              ['成功']
            ]
          }
        }
      ]
    }, 'data[0].info.test[0][0]')
    
    res ----> 成功