如何按XPIns对指定Guild下的用户JSON数据降序排序?
问题描述
我有一个存储GuildID与UserID的JSON数据,示例中GuildID为385524088980111362的服务器下有两位用户,需要按XPIns字段降序排序(使XPIns为7的用户排在首位)。此前的排序代码无法处理带GuildID的嵌套结构,附上过往参考代码与实现的排行榜代码,请求技术帮助。
示例JSON结构
{ "385524088980111362": { "672748733737467936": { "XP": 0, "Level": 1, "BisLevel": 100, "NächsteXP": 0, "XPIns": 2 }, "866935358448468008": { "XP": 0, "Level": 1, "BisLevel": 100, "NächsteXP": 0, "XPIns": 7 } } }
过往参考排序代码
let obj; fs.readFile('./xpdata.json', 'utf8', function (err, data) { if (err) throw err; obj = JSON.parse(data) var sorted = Object.entries(obj).sort((a, b) => b[1] - a[1]) });
过往实现的排行榜代码
let obj; fs.readFile('./userdata.json', 'utf8', function (err, data) { if (err) throw err; try { obj = JSON.parse(data) } catch (error) { if(error) return console.log("Ein Fehler ist aufgetreten! " + error); } var sorted = Object.entries(obj).sort((a, b) => b[1].Economy.Balance - a[1].Economy.Balance) if(sorted.length > 10) sorted = sorted.slice(0, 10) var lBString = ""; var s = 1; sorted.forEach(user => { let usertag = Data[user[0]].Tag lBString += `${s}. ${usertag} • **${user[1].Economy.Balance}$**\n` s = s += 1 }) let embed = { title: `Leaderboard Balance`, description: lBString, color: 0xFFFF00, thumbnail: { url: client.user.avatarURL(), }, timestamp: new Date(), footer: { text: footer, icon_url: client.user.avatarURL(), }, } e.reply({embeds: [embed]}); });
解决方案
针对嵌套的GuildID-UserID结构,只需先定位到目标服务器的用户数据集合,再对该集合内的用户按XPIns字段排序即可。以下是修改后的完整代码:
let obj; // 替换为你要生成排行榜的目标GuildID const targetGuildId = "385524088980111362"; fs.readFile('./xpdata.json', 'utf8', function (err, data) { if (err) throw err; try { obj = JSON.parse(data); } catch (error) { return console.log("发生错误!" + error); } // 检查目标服务器是否存在数据 if (!obj[targetGuildId]) { return console.log("该服务器暂无用户数据"); } // 将目标服务器下的用户数据转为键值对数组,按XPIns降序排序 const sortedUsers = Object.entries(obj[targetGuildId]) .sort((a, b) => b[1].XPIns - a[1].XPIns); // 只保留前10名 if (sortedUsers.length > 10) sortedUsers = sortedUsers.slice(0, 10); // 构建排行榜文本 let lBString = ""; let rank = 1; sortedUsers.forEach(user => { const userId = user[0]; const userData = user[1]; // 这里替换为你获取用户Tag的逻辑,比如从客户端缓存中获取 const usertag = Data[userId]?.Tag || `用户ID: ${userId}`; lBString += `${rank}. ${usertag} • **XPIns: ${userData.XPIns}**\n`; rank++; }); // 创建排行榜Embed const embed = { title: `服务器XPIns排行榜`, description: lBString || "暂无用户数据", color: 0x00FF00, thumbnail: { url: client.user.avatarURL(), }, timestamp: new Date(), footer: { text: footer, icon_url: client.user.avatarURL(), }, }; e.reply({embeds: [embed]}); });
关键修改说明:
- 定位目标服务器数据:通过
obj[targetGuildId]直接获取指定服务器下的所有用户数据,解决嵌套结构的问题。 - 排序逻辑调整:排序时访问
b[1].XPIns和a[1].XPIns,针对用户数据中的XPIns字段进行降序比较。 - 容错处理:增加了目标服务器不存在数据的判断,避免报错。
- 适配XP数据结构:修改了排行榜文本的内容,匹配
XPIns字段的展示需求。
内容的提问来源于stack exchange,提问作者Augenblick
相关产品推荐
相关产品推荐

