首页 > 解决方案 > 如何在 discord.js 中使用 JSON 数据库制作排行榜

问题描述

我想在我的不和谐机器人中创建一个排行榜。

已经开始使用它,我制作了一个 JSON 经典数据库,其中只有userIDCoins列。

{"3879720334874588161":{"coins":5},"3919222756303420417":{"coins":5}}

现在我会用这个数据库做一个排行榜,但我有一些问题:

(node:15500) UnhandledPromiseRejectionWarning: TypeError: coins.sort is not a function
    at Object.module.exports.run (c:\Users\StarKleey\Desktop\Bot discord\Bot Folletto\Commandes\list.js:9:9)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
warning.js:32
(node:15500) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
warning.js:32
(node:15500) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我的代码如下

const Discord = require("discord.js");
const fs = require('fs');

module.exports.run = async (client, message, args) => {
  await message.delete();

  let coins = JSON.parse(fs.readFileSync("./coins.json", "utf8"));

  coins.sort([
    ['coins', 'descending']
  ]).exec((err, res) => {
    if (err) console.log(err);

    let embed = new Discord.MessageEmbed()
      .setTitle("Coins Leaderboard")
    //if there are no results
    if (res.length === 0) {
      embed.setColor("RED");
      embed.addField("No data found", "Please type in chat to gain coins!")
    } else if (res.length < 10) {
      //less than 10 results
      embed.setColor("BLURPLE");
      for (i = 0; i < res.length; i++) {
        let member = message.guild.members.get(res[i].userID) || "User Left"
        if (member === "User Left") {
          embed.addField(`${i + 1}. ${member}`, `**Coins**: ${res[i].coins}`);
        } else {
          embed.addField(`${i + 1}. ${member.user.username}`, `**Coins**: ${res[i].coins}`);
        }
      }
    } else {
      //more than 10 results
      embed.setColor("BLURPLE");
      for (i = 0; i < 10; i++) {
        let member = message.guild.members.get(res[i].userID) || "User Left"
        if (member === "User Left") {
          embed.addField(`${i + 1}. ${member}`, `**Coins**: ${res[i].coins}`);
        } else {
          embed.addField(`${i + 1}. ${member.user.username}`, `**Coins**: ${res[i].coins}`);
        }
      }
    }

    message.channel.send(embed);
  })
}
module.exports.help = {
  name: "leaders"
}

有人可以解决我的问题或知道制作排行榜的另一种解决方案吗?

标签: javascriptnode.jsdatabasediscord.js

解决方案


你的错误是这样说的coins.sort() is not a function

您的硬币变量是一个对象。如果您查看MDN / 另一个网站以了解对象上可用的方法,您会发现没有可用的排序方法。

所以你试图调用一个不存在的函数,因此出现错误。

当前存储用户和硬币的方式(不推荐)

如果您想使用当前文件对硬币对象进行排序,您可以使用

const sorted = [];
const keys = Object.keys(coins)

for (let user in coins) {
  const coin = coins[user].coins;
  
  const entry = {[keys[sorted.length]] : coins[user]}
  
  if (sorted.length === 0) {
    sorted.push(entry);

    continue;
  }
  let i = 0;
  while (sorted[i] !== undefined && sorted[i][Object.keys(sorted[i])].coins > coin) {
    i++;
  }
    
  sorted.splice(i, 0, entry)
}

JSFiddle 示例

我存储用户然后排序的方式(推荐)

我建议用硬币保存您的用户:

[{userID: "123", coins: 12}, ]

那么你可以使用

betterCoins.sort((a,b)=>{b.coins - a.coins});

JSFiddle 示例

您也可以将 Object 转换为数组并使用推荐的方法,而无需更改文件的结构:

const newCoins = [];

for(let userObj in coins){
    newCoins.push({"name" : userObj, "coins": coins[userObj].coins })
}

推荐阅读