Как сделать таблицу лидеров с базой JSON в Discord. js - PullRequest
0 голосов
/ 05 мая 2020

Я хотел бы создать таблицу лидеров, чтобы она была в моем боте Discord.

Уже для запуска я создал базу данных JSON classi c только с столбцами userID и Coins .

{"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"
}

Может ли кто-нибудь решить мою проблему или узнать другое решение для построения таблицы лидеров?

1 Ответ

0 голосов
/ 05 мая 2020

В вашей ошибке говорится, что 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

Вы также можете просто преобразовать свой объект в массив и использовать рекомендуемый метод без необходимости изменять структуру вашего файла:

const newCoins = [];

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