简体   繁体   English

如何在嵌入 [discord.js] 中发布排行榜

[英]How to post leaderboard in embed [discord.js]

I have a discord.js leveling system that stores peoples levels in a json file database.json like this: {"626916199783071750":{"xp":54,"level":14} I am sorting everyone's levels using this code: I have a discord.js leveling system that stores peoples levels in a json file database.json like this: {"626916199783071750":{"xp":54,"level":14} I am sorting everyone's levels using this code:

members.sort(function(a, b) {
  const keyA = a[Object.keys(a)[0]].level,
        keyB = b[Object.keys(a)[0]].level;
  // Compare
  // (swap -1 and 1 to change sort order)
  if(keyA < keyB) return -1;
  if(keyA > keyB) return 1;
  return 0;
});
console.log(members);

(members is being defined with const members = [require("./database.json")]; ) I am able to log it fine and it is in the correct order but I was wondering how I would send that in an embed as this code was not working: (成员是用const members = [require("./database.json")];定义的)我能够很好地记录它并且它的顺序正确,但我想知道如何将它作为嵌入发送此代码不起作用:

      let embed = new Discord.RichEmbed()
      .setColor(0x4286f4)
      .addField('Level:', members)
      member.channel.send(embed);

This was giving me an embed with just undefined as a field.这给了我一个未定义为字段的嵌入。 For reference i am using discord.js v12+作为参考,我正在使用 discord.js v12+

After editing multiple times and talking with you below, I allow myself to make some changes to your bot's way of functioning.在多次编辑并在下面与您交谈后,我允许自己对您的机器人的运行方式进行一些更改。

Data storage数据存储

First of all, the way you store data is kind of bad.首先,您存储数据的方式有点糟糕。 JSON is a bad choice and is very annoying to use as a DB, but it remains an option. JSON 是一个糟糕的选择,用作数据库非常烦人,但它仍然是一个选项。 You should check out Quick.db , which is excellent for beginners, On the other hand, you always , always, want to store documents in an array.您应该查看Quick.db ,它非常适合初学者,另一方面,您总是希望将文档存储在数组中。 Arrays are literally made for that. Arrays 就是为此而生的。 Here's some code to switch your current data to the new model.这里有一些代码可以将您的当前数据切换到新的 model。 Don't forget to also update the other parts of your bot that store data so it matches the new shape.不要忘记更新机器人中存储数据的其他部分,使其与新形状相匹配。 I don't want to make too many changes, but I'd like to add that storing the level is a bad idea, since it depends on xp .我不想做太多的改变,但我想补充一点,存储level是个坏主意,因为它取决于xp You should write a function that converts xp into level and use it, instead of storing level .您应该编写一个 function 将xp转换为level并使用它,而不是存储level

 // const fs = require("fs") // const oldDb = JSON.parse(fs.readFileSync("database.json")) const oldDb = { "626916199783071750": { "xp": 69, "level": 14 }, "579776588732956674": { "xp": 2, "level": 13 }, "784566696244674621": { "xp": 99, "level": 1 }, "495304082769051660": { "xp": 6, "level": 1 }, "752987763573391411": { "xp": 1, "level": 0 } } let newDb = Object.keys(oldDb).map((id) => ({ id, xp: oldDb[id].xp, level: oldDb[id].level }) ) console.log(newDb) // fs.writeFile("database.json", JSON.stringify(newDb), 'utf8')

Sorting by level按级别排序

From that point, you'll be able to work in a much more efficient way.从那时起,您将能够以更有效的方式工作。 Since we've changed the bot's data model, I'll help you convert the sorting method into one that actually works.由于我们更改了机器人的数据 model,我将帮助您将排序方法转换为实际有效的排序方法。

 // const users = require("./database.json"), with the new data model this time const users = [{ id: "626916199783071750", level: 14, xp: 69 }, { id: "579776588732956674", level: 13, xp: 2 }, { id: "784566696244674621", level: 1, xp: 99 }, { id: "495304082769051660", level: 1, xp: 6 }, { id: "752987763573391411", level: 0, xp: 1 }] const sortedUsers = users.sort((a, b) => (a.level > b.level)? 1: -1) // ternary operation, it's basically just a 'if' console.log(sortedUsers)

Post leaderboard发布排行榜

Ah, you did it, Now.啊,你做到了,现在。 here's my original answer... how to send all that data.这是我的原始答案......如何发送所有数据。 You'd need to add a field for each member.您需要为每个成员添加一个字段。 MessageEmbed#addFields() is perfect here. MessageEmbed#addFields()在这里很完美。 The code below isn't tested.下面的代码未经测试。

const maxNumberOfUsersToDisplay = 10;

const embed = new Discord.MessageEmbed().setColor(0x4286f4).addFields(
  sortedUsers.flatMap((userDoc, i) => {
    // flatMap will map and delete all the [] of the array
    if (!(i < maxNumberOfUsersToDisplay && i < 25)) return [];

    return {
      name: user.id, // Feel free to mess with the code and replace this with a mention/tag
      value: `Level ${user.level}`,
      inline: false, // default value, just to show you you can adjust this param to change the embed layout
    };
  })
);

message.channel.send(embed);

Array#flatMap() acts like a .map() and a .flat() , it's an obscure method that should be used more often: it can also be used as a .map() and a .filter() , as shown above. Array#flatMap()的作用类似于.map().flat() ,它是一种晦涩难懂的方法,应该更频繁地使用:它也可以用作.map().filter() ,如图所示以上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM