如何按某个属性排序映射
How to map by sorting by a certain property
我想制作一个功能,让我的机器人...
- 排除类别中的 # 和 VC 频道
- 按数字位置而不是字母顺序对频道进行排序
问题是我不知道如何根据频道的类型将 # 从频道中拆分出来。我也想不出一种方法来按位置编号对频道进行排序。
我试过了
.addField("Server's channels", serv.channels.calculatedPosition.map(c =>
${c}).join(' | '),true)
.addField("Server's channels", serv.channels.map(c =>
${c}).position.join(' | '),true)
var serv = message.guild
var myInfo = new discord.RichEmbed()
.setAuthor(`${serv.name}'s channels`,`${message.guild.iconURL}`)
.addField(`Server's channels`, serv.channels.map(c => `${c}`).join(' | '),true)
.setColor(0xffd000)
.setFooter('Server Roles.')
.setThumbnail(`${message.guild.iconURL}`)
message.channel.sendEmbed(myInfo);
预期:discord.js-commando 命令,它从非文本的频道中拆分 # 并按位置映射频道。
实际:机器人按字母顺序映射频道。
排序
GuildChannel.position
和 GuildChannel.calculatedPosition
的问题是返回的位置基于频道类型。比如,所有的类别都排序并编号,与文字频道分开,文字频道与语音频道分开。
为了解决这个问题,我们可以制作自己的系统来利用它。我们首先对所有类别进行排序并将其添加到一个集合中,并与它们 children 的排序集合配对。然后,我们遍历并将频道添加到列表中。
格式化
从技术上讲,#
符号 应该 位于 non-text 频道之前,因为 Discord 将他们的提及转换为使用它。不过,看起来不是很吸引人,逻辑好像也有点问题。
如果不是文本频道,我们所要做的就是使用频道名称而不是提及。
代码
您可能需要更改一些变量,然后根据需要实施嵌入。这只是一个例子。
const guild = message.guild;
// Comparison function which sorts channels according to appearance within Discord. Name
// is short for 'descending position,' but it also accomodates for voice channel location.
const descPos = (a, b) => {
if (a.type !== b.type) {
if (a.type === 'voice') return 1;
else return -1;
} else return a.position - b.position;
};
// Create a new Collection to hold categories and their children.
const channels = new Discord.Collection();
// Non-category channels without parent categories will appear at the top.
channels.set('__none', guild.channels.filter(channel => !channel.parent && channel.type !== 'category').sort(descPos));
// Add all the categories in order, mapped by their bolded name, into the Collection.
const categories = guild.channels.filter(channel => channel.type === 'category').sort(descPos);
categories.forEach(category => channels.set(category.id, category.children.sort(descPos)));
const list = [];
// Iterate through the categories and the corresponding Collection of their channels.
for (let [categoryID, children] of channels) {
// Retrieve the category from it's ID.
const category = guild.channels.get(categoryID);
// Push the category name (bolded for readability) into the list.
if (category) list.push(`**${category.name}**`);
// Iterate through the Collection of children. Push the mention for text, name for others.
for (let [, child] of children) list.push(child.type === 'text' ? child : child.name);
// To answer your comment about adding the emoji for voice channels...
// list.push(child.type === 'text' ? child : ` ${child.name}`);
}
// Send the list of channels, appearing exactly how it does on the side. Make sure the
// joined list isn't too long for a message or embed field first to avoid an error.
message.channel.send(list.join('\n'))
.catch(console.error);
资源
Discord.js 文档:
我想制作一个功能,让我的机器人... - 排除类别中的 # 和 VC 频道 - 按数字位置而不是字母顺序对频道进行排序
问题是我不知道如何根据频道的类型将 # 从频道中拆分出来。我也想不出一种方法来按位置编号对频道进行排序。
我试过了
.addField("Server's channels", serv.channels.calculatedPosition.map(c =>
${c}).join(' | '),true)
.addField("Server's channels", serv.channels.map(c =>
${c}).position.join(' | '),true)
var serv = message.guild
var myInfo = new discord.RichEmbed()
.setAuthor(`${serv.name}'s channels`,`${message.guild.iconURL}`)
.addField(`Server's channels`, serv.channels.map(c => `${c}`).join(' | '),true)
.setColor(0xffd000)
.setFooter('Server Roles.')
.setThumbnail(`${message.guild.iconURL}`)
message.channel.sendEmbed(myInfo);
预期:discord.js-commando 命令,它从非文本的频道中拆分 # 并按位置映射频道。 实际:机器人按字母顺序映射频道。
排序
GuildChannel.position
和 GuildChannel.calculatedPosition
的问题是返回的位置基于频道类型。比如,所有的类别都排序并编号,与文字频道分开,文字频道与语音频道分开。
为了解决这个问题,我们可以制作自己的系统来利用它。我们首先对所有类别进行排序并将其添加到一个集合中,并与它们 children 的排序集合配对。然后,我们遍历并将频道添加到列表中。
格式化
从技术上讲,#
符号 应该 位于 non-text 频道之前,因为 Discord 将他们的提及转换为使用它。不过,看起来不是很吸引人,逻辑好像也有点问题。
如果不是文本频道,我们所要做的就是使用频道名称而不是提及。
代码
您可能需要更改一些变量,然后根据需要实施嵌入。这只是一个例子。
const guild = message.guild;
// Comparison function which sorts channels according to appearance within Discord. Name
// is short for 'descending position,' but it also accomodates for voice channel location.
const descPos = (a, b) => {
if (a.type !== b.type) {
if (a.type === 'voice') return 1;
else return -1;
} else return a.position - b.position;
};
// Create a new Collection to hold categories and their children.
const channels = new Discord.Collection();
// Non-category channels without parent categories will appear at the top.
channels.set('__none', guild.channels.filter(channel => !channel.parent && channel.type !== 'category').sort(descPos));
// Add all the categories in order, mapped by their bolded name, into the Collection.
const categories = guild.channels.filter(channel => channel.type === 'category').sort(descPos);
categories.forEach(category => channels.set(category.id, category.children.sort(descPos)));
const list = [];
// Iterate through the categories and the corresponding Collection of their channels.
for (let [categoryID, children] of channels) {
// Retrieve the category from it's ID.
const category = guild.channels.get(categoryID);
// Push the category name (bolded for readability) into the list.
if (category) list.push(`**${category.name}**`);
// Iterate through the Collection of children. Push the mention for text, name for others.
for (let [, child] of children) list.push(child.type === 'text' ? child : child.name);
// To answer your comment about adding the emoji for voice channels...
// list.push(child.type === 'text' ? child : ` ${child.name}`);
}
// Send the list of channels, appearing exactly how it does on the side. Make sure the
// joined list isn't too long for a message or embed field first to avoid an error.
message.channel.send(list.join('\n'))
.catch(console.error);
资源
Discord.js 文档: