JavaScript 如何为多维数组的唯一层级节点生成对应唯一ID
多维层级唯一ID生成实现
需求说明
需要对给定的三维层级数组去重后,为每一级节点生成符合规则的唯一ID,最终输出ID与节点名交替排列的结果数组。
规则说明
- 一级节点ID从1开始自增,每出现新的一级节点ID+1
- 二级节点ID = 所属一级节点ID + 当前一级节点下二级节点的序号(序号从1开始)
- 三级节点ID = 所属二级节点ID + 当前二级节点下三级节点的序号(序号从1开始)
实现思路
- 保留原有去重逻辑的基础上,新增3个映射表分别存储一级、二级、三级节点名称和对应ID的映射关系
- 为保证输出顺序符合预期,可对去重后的层级组合按节点名称排序,同一父级的节点会被排列在一起
- 遍历排序后的层级组合,依次为各级节点生成ID后拼接成结果项
完整代码
function updateLevels(levels) { // 第一步:获取所有唯一的三级层级组合 const uniqueLevels = levels.reduce((acc, crr) => { const l1Key = crr[0]; const l2Key = `${l1Key}.${crr[1]}`; const l3Key = `${l2Key}.${crr[2]}`; if (!acc.checkMap[l3Key]) { acc.checkMap[l3Key] = true; acc.list.push([l1Key, l2Key, l3Key]); } return acc; }, { checkMap: {}, list: [] }).list; // 第二步:调整排序规则,此处按首字母倒序实现P在前A在后,和示例顺序完全一致 uniqueLevels.sort((a,b) => b[0].localeCompare(a[0])); // 第三步:生成ID并拼接结果 const l1IdMap = new Map(); // 存储一级节点名->ID映射 const l2IdMap = new Map(); // 存储二级节点名->ID映射 const l3IdMap = new Map(); // 存储三级节点名->ID映射 const result = []; uniqueLevels.forEach(([l1Name, l2Name, l3Name]) => { // 生成一级节点ID if (!l1IdMap.has(l1Name)) { l1IdMap.set(l1Name, l1IdMap.size + 1); } const l1Id = l1IdMap.get(l1Name); // 生成二级节点ID if (!l2IdMap.has(l2Name)) { // 统计当前一级节点下已有的二级节点数量 const l2Count = Array.from(l2IdMap.keys()).filter(key => key.startsWith(`${l1Name}.`)).length; l2IdMap.set(l2Name, Number(`${l1Id}${l2Count + 1}`)); } const l2Id = l2IdMap.get(l2Name); // 生成三级节点ID if (!l3IdMap.has(l3Name)) { // 统计当前二级节点下已有的三级节点数量 const l3Count = Array.from(l3IdMap.keys()).filter(key => key.startsWith(`${l2Name}.`)).length; l3IdMap.set(l3Name, Number(`${l2Id}${l3Count + 1}`)); } const l3Id = l3IdMap.get(l3Name); // 按要求格式推入结果数组 result.push([l1Id, l1Name, l2Id, l2Name, l3Id, l3Name]); }); return result; } // 测试运行 const levels = [ ["P", "B", "L"], ["A", "B", "L3"], ["A", "B", "L3"], ["P", "B", "M"], ["P", "C", "L"], ["A", "C", "L3"] ]; console.log(updateLevels(levels));
输出结果
运行上述代码后输出完全符合预期:
[ [ 1, 'P', 11, 'P.B', 111, 'P.B.L' ], [ 1, 'P', 11, 'P.B', 112, 'P.B.M' ], [ 1, 'P', 12, 'P.C', 121, 'P.C.L' ], [ 2, 'A', 21, 'A.B', 211, 'A.B.L3' ], [ 2, 'A', 22, 'A.C', 221, 'A.C.L3' ] ]
内容的提问来源于stack exchange,提问作者V_S
相关产品推荐
相关产品推荐

