У меня есть система уровней 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()



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


После многократного редактирования и разговора с вами ниже, я позволю себе внести некоторые изменения в способ функционирования вашего бота.
Прежде всего, то, как вы храните данные, довольно плохо. 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