У меня есть система уровней discord.js, которая хранит уровни людей в файле json database.json
вот так: {"626916199783071750":{"xp":54,"level":14}
Я сортирую уровни всех, используя этот код:
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.info(members);
(участники определяются с помощью const members = [require("./database.json")];
)
Я могу зарегистрировать его нормально, и он находится в правильном порядке, но мне было интересно, как я отправлю это во встраивание, поскольку этот код не работает:
let embed = new Discord.RichEmbed()
.setColor(0x4286f4)
.addField('Level:', members)
member.channel.send(embed);
Это дало мне вставку с неопределенным полем. Для справки я использую discord.js v12+
теперь я получаю TypeError: Cannot read property 'client' of undefined
я думаю, что это вызвано где-то еще, пожалуйста, проверьте номер строки, в которой возникает ошибка.
Я не верю, что discord.js позволяет напрямую устанавливать поля для встраивания или содержимое сообщения в массивы/объекты. Вам нужно будет преобразовать массив в строку, прежде чем добавлять его в поле встраивания. Что касается Cannot read property 'client' of undefined
, эта ошибка не связана с этой проблемой и находится где-то еще в вашем коде.
Он говорит, что это происходит в строке кода let embed = new Discord.RichEmbed()
После многократного редактирования и разговора с вами ниже, я позволю себе внести некоторые изменения в способ функционирования вашего бота.
Прежде всего, то, как вы храните данные, довольно плохо. JSON — плохой выбор, и его очень раздражает использование в качестве БД, но он остается вариантом. Вы должны проверить Quick.db, который отлично подходит для начинающих! С другой стороны, вы всегда, всегда хотите хранить документы в массиве. Массивы буквально созданы для этого. Вот некоторый код для переключения ваших текущих данных на новую модель. Не забудьте также обновить другие части вашего бота, в которых хранятся данные, чтобы они соответствовали новой форме. Я не хочу вносить слишком много изменений, но я хотел бы добавить, что хранить level
— плохая идея, так как это зависит от xp
. Вы должны написать функцию, которая преобразует 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.info(newDb)
// fs.writeFile("database.json", JSON.stringify(newDb), 'utf8')
С этого момента вы сможете работать гораздо эффективнее. Поскольку мы изменили модель данных бота, я помогу вам преобразовать метод сортировки в действительно работающий.
// 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.info(sortedUsers)
Ах, ты сделал это! А теперь мой первоначальный ответ... как отправить все эти данные. Вам нужно будет добавить поле для каждого члена. MessageEmbed#addFields() идеально подходит. Код ниже не тестировался.
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() действует как .map()
и .flat()
, это неясный метод, который следует использовать чаще: его также можно использовать как .map()
и .filter()
, как показано выше.
вот ссылка на мою базу данных, должно ли то, что вы отправляете, все еще работать? источникb.in/x4hsyLxeaf
Почему тогда вы используете sort
? Это объект... Не могли бы вы дать мне, что console.info(members)
выводит?
журнал получает меня Ссылка на изображение
Хорошо. Почему вы используете [require('database-file')]
? Какова цель []
? В нем всего 1 элемент, поэтому метод sort
ничего не делает.
если я этого не сделаю, это даст мне TypeError: members.sort is not a function
Я отредактировал сообщение. Если вы все делаете правильно, это должно работать, пожалуйста, задайте мне / отредактируйте свой вопрос, если у вас есть другие вопросы!
(кстати, этот []
бесполезен: он просто помещает вашу базу данных в массив, и, поскольку это единственный элемент, сортировка элементов абсолютно ничего не даст. Вы можете проверить это, если хотите: [db] === [db].sort()
вернет true
)
Будет ли этот код работать со всеми закомментированными строками? Также @a2br большое спасибо за ваше время и помощь, это действительно много значит для меня!
В закомментированных строках используется fs. Первые два добавляют fs в качестве зависимости и используют его для получения БД из вашего JSON. Я прокомментировал их, потому что фрагменты SO не поддерживают require(), поэтому вместо этого я жестко запрограммировал вашу БД (это, конечно, то, что вы не хотите делать). Последняя закомментированная строка записывает новый контент в БД. Убедитесь, что вы обновили остальную часть своего кода, прежде чем обновлять способ хранения данных в БД, это приведет к ошибкам. Я хотел бы добавить, что fs лучше, чем require, когда дело доходит до открытия файлов JSON, потому что он не кэширует их.
Это должно быть
new Discord.MessageEmbed()
, потому что вы используете v12 Discord.js