You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.js打乱对象数组后Embed展示首个元素名称错乱求助

问题分析与解决:Discord.js游戏列表展示异常

问题场景

我用Discord.js编写代码,从MongoDB的gameSchema查询游戏数据,通过shuffle-array打乱数组后,将前16条数据的信息展示在MessageEmbed中。但运行命令时发现,首个展示元素的GameName会显示随机字符(如em、ial),数据库中并无对应名称。

业务代码

const items = require('../schemas/gameSchema');
const items0 = await items.find();
var shuffle = require('shuffle-array');

const items1 = shuffle(items0);

const lb = items1
  .slice(0)
  .map(
    ({ DepositAmount, BetAmount, GameName, TotalPlays }, pos) =>
      `**${GameName}** \n Initial Deposit Amount: **${commaNumber(
        DepositAmount,
      )}** <:bob:809551218217058354> \n Bet Amount:  **${commaNumber(
        BetAmount,
      )}** <:bob:809551218217058354> \n Total Game Plays : ${commaNumber(
        TotalPlays,
      )} 🕹 \n `,
  )
  .join('\n');
const lbnewnew = lb.slice(15);
const newlb = lbnewnew.toString();
let exampleEmbed = new Discord.MessageEmbed()
  .setColor('RANDOM')
  .setTitle('Discover Games')
  .setDescription(`${newlb}`)
  .setTimestamp()
  .setFooter(`You can play games with /game play <game name>`);

await interaction.reply({ embeds: [exampleEmbed] });

游戏Schema定义

const mongoose = require('mongoose')

const adSchema = mongoose.Schema({
    User:String,
    Funds:Number,
    ProfitToClaim:Number,
    TotalProfit:Number,
    TotalLoss:Number,
    DepositAmount:Number,
    BetAmount:Number,
    TotalPlays:Number,
    TotalWins:Number,
    TotalLosses:Number,
    GameName:String,
    GameDescription:String,
})
module.exports = mongoose.model('NewGames', adSchema, 'NewGames')

问题原因

核心错误出在字符串切片的逻辑:

  • 你先把所有游戏的信息拼接成了一个长字符串lb,然后执行lb.slice(15)直接从索引15开始截取字符串。
  • 第一个游戏的名称是用**${GameName}**包裹的,假设第一个游戏名称是"Example Game",拼接后的字符串开头是**Example Game** ...,从索引15截断会直接切掉前15个字符,把名称的后半部分(比如"ame")或者后续无关内容当成了开头,就出现了所谓的"随机字符"。
  • 同时,你原本想取前16条数据,但items1.slice(0)是保留全部数据,后续没有做数组截断,反而通过字符串切片来处理,完全搞错了数据筛选的逻辑顺序。

解决方法

步骤1:先截断数组,只保留前16条数据

对打乱后的数组直接做切片,获取前16条:

const top16Games = items1.slice(0, 16);

步骤2:直接对筛选后的数组做拼接

基于前16条数据生成展示字符串,不需要先拼接全部数据再切字符串:

const lb = top16Games
  .map(
    ({ DepositAmount, BetAmount, GameName, TotalPlays }) =>
      `**${GameName}** \n Initial Deposit Amount: **${commaNumber(DepositAmount)}** <:bob:809551218217058354> \n Bet Amount:  **${commaNumber(BetAmount)}** <:bob:809551218217058354> \n Total Game Plays : ${commaNumber(TotalPlays)} 🕹 \n `,
  )
  .join('\n');

步骤3:移除错误的字符串切片逻辑

直接用生成好的lb作为Embed的描述内容:

let exampleEmbed = new Discord.MessageEmbed()
  .setColor('RANDOM')
  .setTitle('Discover Games')
  .setDescription(lb)
  .setTimestamp()
  .setFooter(`You can play games with /game play <game name>`);

完整修正后的代码

const items = require('../schemas/gameSchema');
const items0 = await items.find();
var shuffle = require('shuffle-array');

const items1 = shuffle(items0);
// 只取前16条数据
const top16Games = items1.slice(0, 16);

const lb = top16Games
  .map(
    ({ DepositAmount, BetAmount, GameName, TotalPlays }) =>
      `**${GameName}** \n Initial Deposit Amount: **${commaNumber(DepositAmount)}** <:bob:809551218217058354> \n Bet Amount:  **${commaNumber(BetAmount)}** <:bob:809551218217058354> \n Total Game Plays : ${commaNumber(TotalPlays)} 🕹 \n `,
  )
  .join('\n');

let exampleEmbed = new Discord.MessageEmbed()
  .setColor('RANDOM')
  .setTitle('Discover Games')
  .setDescription(lb)
  .setTimestamp()
  .setFooter(`You can play games with /game play <game name>`);

await interaction.reply({ embeds: [exampleEmbed] });

内容的提问来源于stack exchange,提问作者Bob joe12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 15:24:21