js之对象扁平化和数组扁平化

3,894 阅读1分钟

今天在刷面试题,看到了对象扁平化和数组扁平化,因此写这篇文章记录一下。

实现简单的对象扁平化

输入:

image.png

输出:

image.png

代码实现思路:我们可以利用Object.entries获取对象的[key,value]数组,遍历这个数组,进行进一步的判断(判断遍历的值的类型,如果是对象类型就递归调用,如果是普通类型就赋值给对象)。

function flat(item, preKey = "", res = {}) {
  Object.entries(item).forEach(([key, val]) => {
    if (val && typeof val === "object") {
      flat(val, preKey + key + ".", res);
    } else {
      res[preKey + key] = val;
    }
  });
  return res;
}

// 测试
const source = { a: { b: { c: 1, d: 2 }, e: 3 }, f: { g: 2 } };
console.log(flat(source));

实现复杂的对象扁平化

输入:

image.png

输出(注意,省略掉null):

image.png

代码实现思路:其实本质上就是多了一个遍历的obj的类型的判断value的类型判断

const input = {
  a: 1,
  b: [1, 2, { c: true }, [3]],
  d: { e: 2, f: 3 },
  g: null,
};

function flat(obj = {}, preKey = "", res = {}) {
  //空值判断,如果obj是空,直接返回
  if(!obj) return
  //获取obj对象的所有[key,value]数组并且遍历,forEach的箭头函数中用了解构
  Object.entries(obj).forEach(([key,value])=>{
    if(Array.isArray(value)){
      //如果obj是数组,那么key就是数组的index,value就是对应的value
      //obj是数组的话就用[]引起来
      //因为value是数组,数组后面是直接跟元素的,不需要.号
      let temp = Array.isArray(obj) ? `${preKey}[${key}]` : `${preKey}${key}`
      flat(value,temp,res)
    }else if(typeof value === 'object'){
      //因为value是对象类型,所以在末尾需要加.号
      let temp = Array.isArray(obj) ? `${preKey}[${key}].` : `${preKey}${key}.`
      flat(value,temp,res)
    }else{
      let temp = Array.isArray(obj) ? `${preKey}[${key}]` : `${preKey}${key}`
      res[temp] = value
    }
  })
  return res;
}

console.log(flat(input));

实现数组扁平化

数组扁平化相较于对象扁平化更加简单

const arr = [1,2,[3,4,[5,6,[7,8,[9,0]]]]]
console.log(arr.toString().split(',').map(Number))
console.log(arr.flat(Infinity))

function flat (arr){
  return arr.reduce((o,n)=>{
    return o.concat(Array.isArray(n) ? flat(n) : n)
  },[])
}
console.log(flat(arr))

image.png