Я делаю бота Discord и хочу добавить значения JSON, подобные этому
{
"Server ID": {
"01-Ticket": {
User: "Some ID",
Channel_ID: "Some ID"
}
}
}
Я добавил один с помощью fs
, но когда я добавляю другой, он удаляет первое значение ("01-Ticket"
)
Это мой index.js:
channel.send(welcomeEmbed).then(async msg => {
await msg.react("🔒")
let tickets = require('./tickets.json')[msg.guild.id];
tickets[msg.guild.id]
console.info(tickets)
fs.writeFileSync('tickets.json', JSON.stringify(tickets, null, 5))
})
Я пробовал это, можете ли вы сделать код, объясняющий это?
Взгляните на это: stackoverflow.com/questions/36093042/…
Есть ли другой путь? я не хочу использовать массивы.
Вам нужно сделать всего две вещи: создать новое имя для билета (если предыдущее было "01-Билет", то нужно назвать новый "02-Билет") и вставить билет в объект используя свое новое имя.
Решение
Вот полный пример того, как вы могли бы сделать такую вещь:
let tickets = require('./tickets.json');
let newName = "01-Ticket";
if (msg.guild.id in tickets) {
let guildTickets = tickets[msg.guild.id];
let oldName = Object.keys(guildTickets).sort((a,b) => a.localeCompare(b)).pop();
let newNumber = Number(oldName.split("-")[0]) + 1;
let length = newNumber.toString().length;
newName = ("0" + newNumber).slice(-((length - 1) + Math.ceil(2 / length))) + "-Ticket";
}
else {
tickets[msg.guild.id] = {};
}
let ticket = {
User: msg.author.id,
Channel_ID: msg.channel.id
}
tickets[msg.guild.id][newName] = ticket;
fs.writeFileSync('tickets.json', JSON.stringify(tickets, null, 5))
Объяснение
А ниже тот же код, но я прокомментировал каждую новую строку, чтобы вам было легче понять цель всего, что я делаю в этом примере:
let tickets = require('./tickets.json');
let newName = "01-Ticket";
//Check if the guild has any tickets
if (msg.guild.id in tickets) {
//The guild does already have tickets
//Get the tickets for this guild
let guildTickets = tickets[msg.guild.id];
//Take all of the ticket names ("01-Ticket", "02-Ticket", etc.) via Object.keys(),
//sort them in ascending numerical order via .sort(),
//and get the last one (the largest number, or the name of the latest ticket) via .pop()
let oldName = Object.keys(guildTickets).sort((a,b) => a.localeCompare(b)).pop();
//Take the old ticket's name ("01-Ticket"), get its number ("01"), and increment
//it by one (so now it would be "2")
let newNumber = Number(oldName.split("-")[0]) + 1;
//The length of the new number (for "2", the length would be 1)
let length = newNumber.toString().length;
//Now add a single "0" to the start of the name (name so far: "0")
//then add the new number (name so far: "02")
//Then, from the end of the name go back as far as necessary to get the proper name (name so far: "02")
//This works with all amounts of digits (ex: 2 -> "02"; 12 -> "12")
newName = ("0" + newNumber).slice(-((length - 1) + Math.ceil(2 / length))) + "-Ticket";
}
else {
//No tickets have been made in this guild yet
//So set the guild's ticket list to an empty object
tickets[msg.guild.id] = {};
}
//Create the new ticket to add to the guild's ticket list
let ticket = {
User: msg.author.id,
Channel_ID: msg.channel.id
}
//Add the ticket to the guild's ticket list
tickets[msg.guild.id][newName] = ticket;
//Update the tickets.json with your updated 'tickets' object
fs.writeFileSync('tickets.json', JSON.stringify(tickets, null, 5))
Итак, сначала я проверяю, есть ли уже ID гильдии в tickets.json
. Если это не так, мы добавляем его как пустой объект (и добавляем новый билет с именем по умолчанию: «01-Билет»). Если ID гильдии уже есть в файле, то нам нужно создать новое имя для нашего нового билета. Итак, сначала я получаю объект, представляющий билеты гильдии. Затем я получаю все ключи в этом объекте (которые являются именами билетов: «01-Ticket», «02-Ticket» и т. д.). Я сортирую эти ключи от меньшего к большему (поскольку все имена билетов начинаются с цифр, это, по сути, их сортировка по номерам) и извлекаю имя последнего билета в отсортированном списке, используя .pop()
(это имя билета, начинающееся с наибольшего числа). ). Затем я беру номер из этого имени билета и добавляю к нему единицу. Затем я обязательно добавляю «0» в начале имени нового билета, если оно состоит только из одной цифры; Я использую сложную формулу и .slice()
для этого, но вы можете сделать это с помощью простого оператора if
. Затем я создаю сам билет, устанавливая его свойства идентификатора пользователя и идентификатора канала. Наконец, я добавляю билет в список билетов гильдии, обновляя переменную tickets
, а затем обновляя tickets.json
новым значением tickets
.
Создание нового имени в этом коде протестировано и работает. Остальной код не тестировался, но работает точно так же, как и в рабочем коде некоторых моих собственных ботов. Если какая-либо часть этого ответа не имеет смысла или вы заметили ошибку, не стесняйтесь комментировать ее.
Вы можете сначала прочитать файл, затем проанализировать его json и добавить к нему дополнительный json, а затем записать этот новый json в свой
tickets.json