
本文介绍一种清晰、高效且可维护的 javascript 方法,将对象的键按最长公共前缀自动归类为嵌套子对象,适用于配置聚合、路由分组、api 命名空间整理等场景。
本文介绍一种清晰、高效且可维护的 javascript 方法,将对象的键按最长公共前缀自动归类为嵌套子对象,适用于配置聚合、路由分组、api 命名空间整理等场景。
在实际开发中,我们常遇到需要对一组语义相关但命名存在层级关系的键进行逻辑分组的需求——例如 apple、apple-02 和 apple124 显然属于同一语义簇,而 banana 与 bananaPhone 同理。此时,简单地按「包含」关系(如 key.includes(prefix))分组容易误判(如 cat 包含于 category 却非前缀),也不满足「最长公共前缀」这一核心要求。因此,需采用更严谨的匹配策略。
下面是一个经过优化的实现方案,它基于双向前缀判定(即 key.startsWith(prefix) 或 prefix.startsWith(key)),确保仅当两者存在明确的前缀/子串包含关系时才归并,并优先复用已存在的最长合法前缀:
function groupKeysByLongestCommonPrefix(obj) {
const result = {};
for (const key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
const subObj = { [key]: obj[key] };
let matchedPrefix = null;
// 遍历已有分组键,寻找首个满足前缀关系的项(模拟“最长”逻辑)
// 注意:因插入顺序即为原始键序,且新键仅与已有前缀比较,
// 故首次命中即代表当前最长可行前缀(避免后续更短前缀覆盖)
for (const prefix in result) {
if (key.startsWith(prefix) || prefix.startsWith(key)) {
matchedPrefix = prefix;
break;
}
}
if (matchedPrefix) {
Object.assign(result[matchedPrefix], subObj);
} else {
result[key] = subObj;
}
}
return result;
}✅ 使用示例:
const input = {
apple: 3,
'apple-02': { stuff: 'more stuff' },
apple124: 'morestuff',
banana: 5,
bananaPhone: 'morestuff',
cherry: 10,
};
console.log(groupKeysByLongestCommonPrefix(input));
// 输出:
// {
// apple: { apple: 3, 'apple-02': { stuff: 'more stuff' }, apple124: 'morestuff' },
// banana: { banana: 5, bananaPhone: 'morestuff' },
// cherry: { cherry: 10 }
// }⚠️ 关键注意事项:
立即学习“Java免费学习笔记(深入)”;
- 前缀判定是双向的:key.startsWith(prefix) 处理如 apple-02 归入 apple 组;prefix.startsWith(key) 则处理反向情形(如先出现 apple124,后出现 apple),确保分组鲁棒性;
- 非严格“最长”但实践最优:该算法按原始键遍历顺序构建分组,首次匹配即终止内层循环。虽未穷举所有可能前缀组合(那将导致 O(n²) 时间复杂度),但在绝大多数真实场景(键名具有自然前缀层级)下,其结果符合直觉且性能优异;
- 避免原型污染:使用 Object.prototype.hasOwnProperty.call(obj, key) 替代 obj.hasOwnProperty(key),防止目标对象重写 hasOwnProperty 方法引发异常;
- 不支持嵌套对象递归分组:本函数仅作用于顶层键;若需深度处理(如值本身为对象且需继续分组),应封装为递归工具或配合 lodash.groupBy 等库扩展。
? 进阶建议:
如需严格保证“数学意义上最长公共前缀”,可预计算所有键两两间的 LCP(Longest Common Prefix),再构建前缀树(Trie)进行聚类——但这会显著增加时间与空间开销,通常仅在键量极大(>10k)、前缀结构异常复杂时才需考虑。对于日常前端工程与配置管理,上述方案已在可读性、性能与准确性之间取得最佳平衡。










