如何按申请编号排序Discord已处理申请频道?(TypeScript)
问题描述
用户申请加入服务器时,服务器顶部会创建对应申请频道。由于处理申请的顺序不固定,处理完成后频道会被关闭并移至名为“Past Channels”的分类中。目前移至该分类后频道默认置顶,希望实现按频道名称末尾的4位申请编号排序。
使用TypeScript开发,尝试过以下两种代码均未生效:
function setPosition(client: myClient, channel: TextChannel) { const regex = /\d{4}$/; const appnum = Number(regex.exec(channel.name)![0]); console.log(`[SLASH COMMANDS] Application #${appnum} was responded to.`); const category = client.channels.cache.get(client.categoryPastApplications); if (!category || category.type !== ChannelType.GuildCategory) { console.log( `[SLASH COMMANDS] An error occured while executing command "application"! Code #6` ); return; } const channelsCategory = category.children.cache.sort((a, b) => a.position - b.position); channelsCategory.forEach((categoryChannel) => { if (Number(regex.exec(categoryChannel.name)![0]) > appnum) { channel.setPosition(categoryChannel.position + 1); } }); }
编辑补充:修改后的代码仍无效:
async function setPosition(client: myClient, channel: TextChannel) { const regex = /\d{4}$/; const appnum = Number(regex.exec(channel.name)![0]); console.log(`[SLASH COMMANDS] Application #${appnum} was responded to.`); const category = client.channels.cache.get(client.categoryPastApplications); if (!category || category.type !== ChannelType.GuildCategory) { console.log( `[SLASH COMMANDS] An error occured while executing command "application"! Code #6` ); return; } const channelsCategory = category.children.cache.sort((a, b) => a.position - b.position); Object.values(channelsCategory).forEach(async (categoryChannel, index) => { if (Number(regex.exec(categoryChannel.name)![0]) < appnum) { await channel.setPosition(index + 1); } }); }
解决方案
你的代码存在两个核心问题:
- 遍历逻辑错误:多次调用
setPosition会导致频道位置被反复覆盖,最终结果不可控。 - 排序逻辑偏差:原代码基于现有频道的位置排序,而非按申请编号排序来计算目标位置。
正确的实现思路是:
- 获取分类下所有频道,提取每个频道的申请编号
- 找到当前频道编号应插入的位置(即第一个比它大的编号的位置之前)
- 一次性设置频道到目标位置
修改后的代码如下:
async function setPosition(client: myClient, channel: TextChannel) { const regex = /\d{4}$/; const appnumMatch = regex.exec(channel.name); if (!appnumMatch) { console.log(`[SLASH COMMANDS] Invalid channel name format: ${channel.name}`); return; } const appnum = Number(appnumMatch[0]); console.log(`[SLASH COMMANDS] Application #${appnum} was responded to.`); const category = client.channels.cache.get(client.categoryPastApplications); if (!category || category.type !== ChannelType.GuildCategory) { console.log(`[SLASH COMMANDS] An error occured while executing command "application"! Code #6`); return; } // 获取分类下所有文本频道,并按申请编号排序 const sortedChannels = Array.from(category.children.cache.values()) .filter(ch => ch.type === ChannelType.GuildText) .map(ch => { const match = regex.exec(ch.name); return { channel: ch, num: match ? Number(match[0]) : -1 }; }) .filter(item => item.num !== -1) .sort((a, b) => a.num - b.num); // 计算目标位置:找到第一个编号大于当前appnum的频道位置,插入到它前面 let targetPosition = 0; for (const item of sortedChannels) { if (item.num > appnum) { break; } targetPosition++; } // 移动频道到目标位置 await channel.setPosition(targetPosition); }
关键改进点:
- 增加格式校验:避免频道名称不符合格式时出现报错
- 统一排序逻辑:基于申请编号对现有频道排序,而非依赖当前位置
- 单次位置设置:计算出准确目标位置后仅调用一次
setPosition,避免多次操作冲突 - 类型安全处理:过滤非文本频道,确保只处理目标类型的频道
内容的提问来源于stack exchange,提问作者Akshat
相关产品推荐
相关产品推荐

