如何从含层级组的用户列表生成带地址字符串的唯一组列表
实现层级分组提取的
getGroups函数 这是个典型的层级关系处理问题,核心是先构建一个能跟踪组间父子关系和出现顺序的层级树,再通过遍历树生成类IP格式的组地址。下面是具体的实现思路和代码:
实现思路
- 确定层级顺序:用户对象的键是
Level 1、Level 2这类带数字的命名,先把这些按键按层级数字排序,确保我们从最高层级到最低层级依次处理。 - 构建层级树:遍历每个用户的层级链,依次将每个组添加到树中——如果父级组已存在,就把当前组挂到父级的子节点下;如果不存在,就创建新节点。这样能保证每个组只被记录一次。
- 遍历树生成结果:递归遍历层级树,根据父节点的地址和当前组在子节点中的顺序,生成类IP格式的地址,同时收集成目标格式的数组。
代码实现
function getGroups(users) { // 定义层级树的根节点,用Map存储子节点以保留插入顺序 const root = { children: new Map() }; const groups = []; // 逐个处理每个用户的层级链 users.forEach(user => { // 获取并排序用户的层级键(保证从Level 1到Level N的顺序) const levelKeys = Object.keys(user).sort((a, b) => { const levelA = parseInt(a.split(' ')[1]); const levelB = parseInt(b.split(' ')[1]); return levelA - levelB; }); let currentNode = root; levelKeys.forEach(key => { const groupName = user[key]; // 如果当前父节点的子节点中没有这个组,就创建新节点 if (!currentNode.children.has(groupName)) { currentNode.children.set(groupName, { name: groupName, children: new Map() }); } // 移动到当前组节点,继续处理下一层级 currentNode = currentNode.children.get(groupName); }); }); // 递归遍历层级树,生成带地址的组列表 function traverse(node, parentAddress) { // 按插入顺序获取子节点数组 const childNodes = Array.from(node.children.values()); childNodes.forEach((child, index) => { // 计算当前组的地址:父地址 + . + 子节点序号(从1开始计数) const currentAddress = parentAddress ? `${parentAddress}.${index + 1}` : `${index + 1}`; groups.push({ name: child.name, address: currentAddress }); // 递归处理当前组的子节点 traverse(child, currentAddress); }); } // 从根节点开始遍历生成结果 traverse(root, null); return groups; } // 测试示例 const users = [ { 'Level 1': 'first', 'Level 2': 'second', 'Level 3': 'third' }, { 'Level 1': 'first', 'Level 2': 'second', 'Level 3': 'another' } ]; const expectedGroups = [ { name: 'first', address: '1' }, { name: 'second', address: '1.1' }, { name: 'third', address: '1.1.1' }, { name: 'another', address: '1.1.2' } ]; console.log(JSON.stringify(getGroups(users)) === JSON.stringify(expectedGroups)); // 输出true
代码说明
- 层级排序:通过拆分
Level X的键并提取数字,确保我们严格按从高到低的层级处理组,避免出现跨层级的错误。 - Map存储子节点:使用
Map而非普通对象,是因为Map会保留键的插入顺序,这样同级组的序号会按首次出现的顺序生成(比如示例中third先出现,序号为1,another后出现序号为2)。 - 递归遍历:通过递归遍历树结构,自然继承父级的地址,拼接当前组的序号,完美生成类IP格式的层级地址。
内容的提问来源于stack exchange,提问作者Ciryon
相关产品推荐
相关产品推荐

