LuckyWinty / fe-weekly-questions

A pro to record some interview questions every week...
MIT License
341 stars 34 forks source link

实现对象扁平化,代码示例如下 #57

Open LuckyWinty opened 4 years ago

LuckyWinty commented 4 years ago
{ 
  "a": { 
    "b": { 
      "c": { 
        "d": 1 
      } 
    } 
  }, 
  "aa": 2, 
  "c": [ 
    1, 
    2 
  ] 
}
 //输出 { 'a.b.c.d': 1, aa: 2, 'c[0]': 1, 'c[1]': 2 }
LuckyWinty commented 4 years ago

简单版答案

let str = '' 
let o = {} 
function objFlatten (obj) { 
  Object.keys(obj).map(item => { 
    if (Object.prototype.toString.call(obj[item]) === '[object Object]') { 
      str += item + '.' 
      objFlatten(obj[item]) 
    } else if (Object.prototype.toString.call(obj[item]) === '[object Array]') { 
      obj[item].forEach((ele, index) => o[item+`[${index}]`] = ele) 
    } else { 
      str += item 
      o[str] = obj[item] 
      str = '' 
    } 
  }) 
}

优化

参考深拷贝的实现,区分不同的对象类型

LuckyWinty commented 4 years ago
function flatDeep(arr, d = 1) {
   return d > 0 ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatDeep(val, d - 1) : val), []) : arr.slice();
};   

转自MDN

xiaodaobiepao commented 4 years ago
function objFlat(obj) {
    let res = {}
    const __flat = (obj, key) => {
        if (notArrAndObj(obj)) {
            res[key] = obj
            return
        }
        isArray = Array.isArray(obj)
        for (let k in obj) {
            let keyString = ''
            if (!key) {
                keyString = k
            } else {
                if (isArray) {
                    keyString = `${key}[${k}]`
                } else {
                    keyString = key + '.' + k
                }
            }
            __flat(obj[k], keyString)
        }
    }
    __flat(obj, '')
    return res
}
function notArrAndObj(obj) {
   return Object.prototype.toString.call(obj) !== '[object Array]' && Object.prototype.toString.call(obj) !== '[object Object]'
}