基础编程题汇总(一)&& 相对较全的对象扁平化

前言

哈喽啊兄弟们,这是第一篇文章。因为最近在找工作吗。然后恰好自己算法编程这块是硬伤。所以就尝试着整理一下这块的内容,也是给自己一个总结学习的机会。因为是基础编程题,所以不会有太多讲解,直接代码摆上去各位应该就可以看懂了。不理解的可以评论区提问一下。会有好心的大佬讲解的(如果我没回复的话)。


数组扁平化

// 期望效果,将多维数组进行降维。
const arr = [1, [2, [3, 4]]];
console.log(flatten(arr)); // [1, 2, 3, 4]

答题思路: 闭包+递归,通过闭包来存储数据,如何通过递归来遍历这个数组,并把遍历的值存储在result里面。

const arrFlatten = (arr) => {
    let result = [];  // 创建初始数组来存储。
    arr.forEach((item, i, arr) => { // 开始遍历数组
      if (Array.isArray(item)) {
        // 判断是否为数组,是的话递归调用,进行深层便利。
        result = result.concat(flatten(item));
      } else {
        // 不是的话直接push进去存储。
        result.push(arr[i]);
      }
    });
    return result; // 返回最终结果
  };

这个是精简版,使用reduce直接一步到位。

    function flat(arr) {
      return arr.reduce((a, b) => a.concat(b instanceof Array ? flat(b) : b), []);
    }

对象扁平化

好的,接下来我们进阶一下。如果是obj类型不是数组了,怎么办呢?

const obj = {
  a: {
    b: {
      c: null,
    },
    d: null,
  },
  e: {
    f: null,
  },
  g: null,
};

console.log(flat(obj)); 
// { 'a.b.c': null, 'a.d': null, 'e.f': null, g: null }

问题解析: 这里相对于之前的代码其实区别不大,真正的卡点在于,obj类型是没有办法遍历的。

答题思路: 直接使用for of的话会报错。 这个时候就要靠我们的Object.entries()

function flat(item, preKey = "", res = {}) {
  // 将obj变成可被[key:val]的数组形式
  Object.entries(item).forEach(([key, val]) => {
    // 如果是对象类型,则递归调用
    if (val && typeof val === "object") {
      flat(val, preKey + key + ".", res);
    } else {
      // 如果不是,则进行赋值
      res[preKey + key] = val;
    }
  });
  return res;  // 返回最终结果
}

元组扁平化

没错,这个类型依然可以进行升级。如果我们的扁平化是混合数据类型呢?比如下面这种样子。

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

问题解析: 和对象扁平化相比,这里需要新判断一下递归里面的类型。根据不同的类型进行对应的操作判断。
答题思路: 基本类型和对象类型的我们都在之前版本上进行操作了。唯一需要新加判断的是Array类型。我们在最开始的时候加上数组类型的判断即可。

function flat(obj, preKey = "", res = {}) {
  if (!obj) return;

  Object.entries(obj).forEach(([key, val]) => {
    // 判断是否为数组类型,是的话则走数组的命名规则。
    if (Array.isArray(val)) {
      let temp = Array.isArray(obj) ? `${preKey}[${key}]` : `${preKey}${key}`;
      flat(val, temp, res);
    } else if (val && typeof val === "object") {
      // 如果是obj类型,则直接保持之前的样子即可
      let temp = Array.isArray(obj) ? `${preKey}[${key}].` : `${preKey}${key}.`;
      flat(val, temp, res);
    } else {
      // 基础类型的话,直接赋值
      let temp = Array.isArray(obj) ? `${preKey}[${key}]` : `${preKey}${key}`;
      res[temp] = val;
    }
  });
  return res; // 返回最终结果
}

参考

js之对象扁平化和数组扁平化 - 掘金 (juejin.cn)
Object.entries() - JavaScript | MDN (mozilla.org)