#javascript #multidimensional-array #fatal-error
#javascript #многомерный массив #фатальная ошибка
Вопрос:
Я пытаюсь написать Discord-бота на JavaScript и столкнулся с проблемой, окно CMD вылетает на рабочий стол, когда доходит до кода в инструкции: «if (styles.includes(cmd2))», кто-нибудь знает, в чем может быть проблема?
Пользователь должен ввести «!рекомендовать», за которым следует либо «фильм», «игра», либо «шоу». В настоящее время это работает нормально.
Сейчас я пытаюсь добавить случай, когда пользователь может ввести «!рекомендовать», за которым следует жанр или стиль, такой как «научная фантастика». Бот должен выполнить поиск в 2D-массиве «фильмы» для любых фильмов, в списке жанров которых есть «научная фантастика». Это не работает.
У меня есть подозрение, что проблема вызвана утверждением «if (movies[i].includes(cmd2))», однако это скорее ощущение, чем основано на каких-либо реальных логических рассуждениях. Строка «genreMovies [i] [y].push(movies[i] [y]);» также может быть источником проблемы. Любая помощь была бы высоко оценена! Спасибо, что нашли время прочитать это!
Код, показанный ниже:
var Discord = require('discord.io');
var logger = require('winston');
var auth = require('./auth.json');
// Configure logger settings
logger.remove(logger.transports.Console);
logger.add(new logger.transports.Console, {
colorize: true
});
logger.level = 'debug';
// Initialize Discord Bot
var bot = new Discord.Client({
token: auth.token,
autorun: true
});
bot.on('ready', function (evt) {
logger.info('Connected');
logger.info('Logged in as: ');
logger.info(bot.username ' - (' bot.id ')');
});
bot.on('message', function (user, userID, channelID, message, evt) {
// Our bot needs to know if it will execute a command
// It will listen for messages that will start with `!`
if (message.substring(0, 1) == '!') {
var args = message.substring(1).split(' ');
var cmd = args[0];
var cmd2 = args[1];
var styles = [
'cyberpunk',
'dystopia',
'noir',
'thriller',
'sci-fi',
'post-apocalyptic',
'action',
'adventure',
'romantic',
'drama',
'crime',
'horror',
'slasher',
'dark-comedy',
'mystery',
'superhero',
'animated',
'comedy',
'historical',
'fantasy'
];
var gameTypes = [
'point-and-click',
'RPG',
'shooter',
'stealth',
'open-world',
'hack-and-slash'
]
var movies = [
['Blade Runner (1982)', 15, '1h 57m', 'cyberpunk, dystopia, noir' , 'film with a brilliant aesthetic and a great cyberpunk noir tale to tell.'],
['Blade Runner 2049 (2017)', 15, '2h 44m', 'Cyberpunk, Dystopia, Thriller' , 'visually stunning movie set in a cyberpunk world that explores issues surrounding humanity.'],
['Ex Machina (2014)', 15, '1h 48m', 'Sci-Fi, Thriller, Drama, Romance' , 'movie about AI and the issues relating to it with some philisophical questions.']
];
var games = [
['Blade Runner (1997)', 16, '8h 30m', 'point-and-click adventure game that captures the films aesthetic brilliantly and has an intruiging plot.'],
['Borderlands 2 (2012)', 18, '22h 30m', 'very entertaining comedic first person shooter with a cartoony art style.'],
['Deus Ex (2000)', 16, '23h', 'first-person immersive-sim and RPG that delves deep into government conspiracies and capitalistic private agencies.']
];
var tvShows = [
['Altered Carbon (2018-2020)', 18, 2, 18, '56m', "thrilling cyberpunk crime drama set in a world where people's personalities are saved in a 'stack' that can be recovered after death."],
['Ripper Street (2012-2016)', 15, 5, 37, '1h 7m', 'character focused period drama set in the victorian era following Edmund Reid and his colleagues Sergeant Drake and Homer Jackson.'],
['Banshee (2013-2016)', 18, 4, 38, '1h', 'dramatic crime thriller about a criminal who poses as a sheriff in a small southern town with complex characters and emotional payoffs.']
];
args = args.splice(1);
switch(cmd) {
// !recommend
case 'recommend':
switch(cmd2) {
// !recommend movie
case 'movie':
var randInt = getRndInteger(0,3);
bot.sendMessage({
to: channelID,
message: 'You should try ' movies[randInt][0] '. The movie is rated BBFC ' movies[randInt][1] ' and is ' movies[randInt][2] ' long. Genres: ' movies[randInt][3] '. It is a ' movies[randInt][4]
});
break;
// !recommend game
case 'game':
var randInt = getRndInteger(0,3);
bot.sendMessage({
to: channelID,
message: 'You should try ' games[randInt][0] '. The game is rated PEGI ' games[randInt][1] ' and is ' games[randInt][2] ' long. It is a ' games[randInt][3]
});
break;
// !recommend TV show
case 'show':
var randInt = getRndInteger(0,3);
bot.sendMessage({
to: channelID,
message: 'You should try ' tvShows[randInt][0] '. The show is rated BBFC ' tvShows[randInt][1] ' and has ' tvShows[randInt][2] ' seasons with ' tvShows[randInt][3] ' episodes. Each episode is around ' tvShows[randInt][4] ' long. It is a ' tvShows[randInt][5]
});
break;
}
if (styles.includes(cmd2)){
var i;
for (i = 0; i <= movies.length; i ){
if (movies[i].includes(cmd2)) {
var max = 0;
max ;
var genreMovies = [];
var y;
for (y = 0; y <= 4; y ) {
genreMovies[i][y].push(movies[i][y]);
}
}
}
var randInt = getRndInteger(0,max);
bot.sendMessage({
to: channelID,
message: 'You should try ' genreMovies[randInt][0] '. The movie is rated BBFC ' genreMovies[randInt][1] ' and is ' genreMovies[randInt][2] ' long. Genres: ' genreMovies[randInt][3] '. It is a ' genreMovies[randInt][4]
});
}
break;
case 'help':
bot.sendMessage({
to: channelID,
message: "__**List of Commands:**__ n Use *!recommend [mediaType]* e.g. '!recommend movie' and you will get a movie recommendation! n Use *!recommend [genre] [mediaType]* e.g. '!recommend noir movie' and you will get a movie recommendation from that genre! n There are also a number of *hidden commands*! n And as you well know, you can use *!help* to view the command list! n n __**List of Media Types:**__ n movie e.g. '!recommend movie' n game e.g. '!recommend game' n show e.g. '!recommend show'"
});
break;
}
}
});
function getRndInteger(min, max) {
return Math.floor(Math.random() * (max - min) ) min;
}
Комментарии:
1.
genremovies[i][y]
кажется неопределенным. я думаю, вы просто хотитеgenremovies.push(...)
Ответ №1:
movies[i].includes(cmd2)
ведет себя не так, как вы ожидаете. Давайте разберем это:
movies[i]
содержит данные об одном фильме, например: ['Blade Runner (1982)', 15, '1h 57m', 'cyberpunk, dystopia, noir' , 'film with a brilliant aesthetic and a great cyberpunk noir tale to tell.']
Данные, относящиеся к жанру четвертого элемента массива — 'cyberpunk, dystopia, noir'
.
Метод array array.includes(value)
возвращает true, если в массиве есть значение, подобное указанному, поэтому, если пользователь вводит !recommend cyberpunk
, значение будет cyberpunk
. 'cyberpunk' !== 'cyberpunk, dystopia, noir'
.
Я бы рекомендовал структурировать данные фильма как объект, что-то вроде:
{
name: 'Blade Runner',
year: 1982,
genres: ['cyberpunk', 'dystopia', 'noir']
...
}
Тогда вы можете сделать movies[i].genres.includes(cmd2)
.
Затем код выдает ошибку в строке, genreMovies[i][y].push(movies[i][y])
потому что вы определили genreMovies как пустой массив, и вы пытаетесь получить доступ к некоторым, genreMoves[i][y]
которые не определены.