作业帮一面算法:扁平对象

7 阅读2分钟

写在前面

郑重承诺以下内容不由 AI 生成

前段时间面试了作业帮,一面进行到一个多小时的时候,面试官一看时间都十二点了,我也看了一眼时间,心想终于结束了。没想到,面试官贴出来了一个算法题,大意是扁平一个对象,要求输出一个新的对象,key值是扁平化后的字符串,value值是最深的key对应的值,如下图所示:

1.png

遗憾的是,我当时没有写出来解决函数,也失去了进入下一面的机会,本文会分享如何解决这个问题

解题思路

这个题的核心是递归,首先我们需要定义一个函数 flattenObject,它接受一个对象作为参数,并返回一个新的扁平化对象,我们可以使用一个辅助函数来处理递归逻辑。

假如我们有一个简单的对象,这个对象的值都是简单类型的数据,不包含数组和对象,如下:

const obj = { a: 1, b: 2, c: 3 }

这种情况下,我们直接将键值对添加到扁平化对象中,路径就是键本身。我们可以很容易写出来解决函数

function flattenObject(source) {
    const flattened = {};

    function traverse(node) {
        const keys = Object.keys(node);
        for (const key of keys) {
            const value = node[key];
            flattened[key] = value;
        }
    }

    traverse(source);

    return flattened;
}

对象

这里相对来说简单一些,我们只需要处理好 flattened[key] = value 中的 key 就行,在递归调用时将当前键添加到路径前缀中,并在路径后面添加一个点号即可。

数组

需要注意的是,数组的键应该使用方括号来表示,例如 arr[0],而不是 arr.0。所以,在处理数组时,我们需要在路径前缀后面添加一个方括号,并在递归调用时将索引作为路径的一部分。同时,我们还需要在路径后缀中添加一个右方括号,以确保路径的正确格式。

代码实现

function flattenObject(source) {
	const flattened = {};

	function traverse(node, pathPrefix = "", pathSuffix = "") {
		const keys = Object.keys(node);
		for (const key of keys) {
			const value = node[key];
			const fullPath = pathPrefix + key + pathSuffix;
			if (Array.isArray(value)) {
				traverse(value, fullPath + "[", "]");
				continue;
			}
			if (typeof value === "object" && value !== null) {
				traverse(value, fullPath + ".");
			} else {
				flattened[fullPath] = value;
			}
		}
	}

	traverse(source);

	return flattened;
}

测试截图如下

2.jpg

写在最后

感觉您耐心看完这篇文章,希望您能喜欢。这里是《前端毕业班》,前端开发者的自救互助小组。在 AI 与不确定性并存的时代,我们一起看清焦虑,聊技术、聊趋势,也聊前端还能走多远,走去哪。