You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按申请编号排序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会导致频道位置被反复覆盖,最终结果不可控。
  • 排序逻辑偏差:原代码基于现有频道的位置排序,而非按申请编号排序来计算目标位置。

正确的实现思路是:

  1. 获取分类下所有频道,提取每个频道的申请编号
  2. 找到当前频道编号应插入的位置(即第一个比它大的编号的位置之前)
  3. 一次性设置频道到目标位置

修改后的代码如下:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 02:13:20