#javascript #state-machine
Вопрос:
Я решил проблему Подсчета смайликов:
Учитывая массив (arr) в качестве аргумента, выполните функцию countSmileys, которая должна возвращать общее количество улыбающихся лиц.
Правила для улыбающегося лица:
- Каждый смайлик должен содержать правильную пару глаз. Глаза могут быть помечены как
:
или;
- У смайлика может быть нос, но это не обязательно. Допустимыми символами для носа являются
-
или~
- У каждого улыбающегося лица должен быть улыбающийся рот, который должен быть отмечен либо
)
илиD
Никакие дополнительные символы не допускаются, за исключением упомянутых.
Допустимые примеры смайликов:
:) :D ;-D :~)
Недопустимые смайлики:;( :> :} :]
Пример
countSmileys([':)', ';(', ';}', ':-D']); // should return 2; countSmileys([';D', ':-(', ':-)', ';~)']); // should return 3; countSmileys([';]', ':[', ';*', ': Примечание В случае пустого массива верните 0. Вы не будете протестированы с неверным вводом (ввод всегда будет массивом). Порядок элементов лица (глаза, нос, рот) всегда будет одинаковым.
Затем, когда я просматриваю решения, я нахожу, что многие люди используют регулярные выражения. Затем я хочу написать государственную машину для реализации регулярного выражения и решения этой проблемы. Но я потерпел неудачу. Это мой код:
function countSmileys(smileys) {
let state = smileyHasValidEye;
return smileys.filter(smiley => {
for (let s of [...smiley]) {
state = state(s);
}
return state === true;
}).length;
}
function smileyHasValidEye(s) {
if (s === ':' || s === ';') {
return smileyHasValidNose;
}
return smileyHasValidEye;
}
function smileyHasValidNose(s) {
if (s === '-' || s === '~') {
return smileyHasValidMouth;
}
return smileyHasValidMouth(s);
}
function smileyHasValidMouth(s) {
if (s === ')' || s === 'D') {
return true;
}
return;
}
console.log(countSmileys([':)', ';(', ';}', ':-D']));
И ошибка, которую я получаю, такова:
state = state(s);
^
TypeError: state is not a function
Затем я отладил свой код и обнаружил, что процедура не входит в smileyHasValidNose
функцию. Тогда я не знаю причины.
Комментарии:
1. не совсем уверен, но я только что заметил, что большинство функций возвращают функцию, в то время как smileyHasValidNose выполняет
return smileyHasValidMouth(s)
вызов, возвращая значение, а не функцию.2. Что это за проблема, о которой вы упомянули? Я не знаком с этим и, следовательно, не знаком с тем, что пытается сделать ваш код. Я не смог бы знать, как это исправить или как использовать какие-либо потенциальные ответы здесь.
3. @VLAZ Проблема со смайликами -это проблема в кодовых войнах, и я хочу решить ее с помощью государственной машины.
4. Это информация, которая относится к вопросу . И не только ссылка - если содержание ссылки меняется или ссылка по какой-либо причине мертва, то вопрос теряет смысл. Я отредактировал вопрос, чтобы включить в него контекст. Пожалуйста, в будущем добавляйте всю соответствующую информацию в вопрос с самого начала.
Ответ №1:
Проблема в том, что вы на самом деле не переключаетесь state
между смайликами. Таким образом, следующим состоянием смайлика будет true
то, которое вы не можете вызвать (это не функция).
Вы можете использовать локальную переменную state
, которая сбрасывает ее в первую функцию (первый шаг).
function countSmileys(smileys) {
let firstStep = smileyHasValidEye;
return smileys.filter(smiley => {
let state = firstStep;
for (let s of [...smiley]) {
state = state(s);
}
return state === true;
}).length;
}
function smileyHasValidEye(s) {
if (s === ':' || s === ';') {
return smileyHasValidNose;
}
return smileyHasValidEye;
}
function smileyHasValidNose(s) {
if (s === '-' || s === '~') {
return smileyHasValidMouth;
}
return smileyHasValidMouth(s);
}
function smileyHasValidMouth(s) {
if (s === ')' || s === 'D') {
return true;
}
return;
}
console.log(countSmileys([':)', ';(', ';}', ':-D']));
Однако этот код приведет к ошибке, если в строке есть что-то еще, кроме смайлика (или его части).
Я бы изменил smileyHasValidMouth
, чтобы вернуться false
, если он не обнаружит смайлик. Просто чтобы быть более последовательным здесь...
function smileyHasValidMouth(s) {
if (s === ')' || s === 'D') {
return true;
}
return false;
}
И отрегулируйте свой цикл так, чтобы он выходил раньше, если он находит значение, которое не является функцией.
for (let s of [...smiley]) {
state = state(s);
if(typeof state !== 'function') return state;
}
function countSmileys(smileys) {
let firstStep = smileyHasValidEye;
return smileys.filter(smiley => {
let state = firstStep;
for (let s of [...smiley]) {
state = state(s);
if (typeof state !== 'function') return state;
}
}).length;
}
function smileyHasValidEye(s) {
if (s === ':' || s === ';') {
return smileyHasValidNose;
}
return smileyHasValidEye;
}
function smileyHasValidNose(s) {
if (s === '-' || s === '~') {
return smileyHasValidMouth;
}
return smileyHasValidMouth(s);
}
function smileyHasValidMouth(s) {
if (s === ')' || s === 'D') {
return true;
}
return false;
}
console.log(countSmileys([':~(', ':>', ':D', ':(', ':o>', ';)', ':)']));
Комментарии:
1. Большое вам спасибо, вы решили мою проблему. Но другая проблема-это когда моя процедура тестирования массив [':~(', ':>', ':Д', ':(', ':О>', ';)', ':)'] он по-прежнему непойманные ошибку TypeError: государство не является функцией в консоли. Я отладил и обнаружил, что это происходит из-за того, что ":o>", второй и третий символы не совпадают. Но я уже давно не придумывал решения. Есть ли подход к ее решению?
2. @Ha0ran да, я изначально собирался написать второе предложение для решения этой проблемы, но я не знал, будет ли оно применимо к вашему делу.
3. @Ha0ran смотрите обновленный пост
4. Это оно. Еще раз спасибо!
, ';-D']); // should return 1;
Примечание
В случае пустого массива верните 0. Вы не будете протестированы с неверным вводом (ввод всегда будет массивом). Порядок элементов лица (глаза, нос, рот) всегда будет одинаковым.
Затем, когда я просматриваю решения, я нахожу, что многие люди используют регулярные выражения. Затем я хочу написать государственную машину для реализации регулярного выражения и решения этой проблемы. Но я потерпел неудачу. Это мой код:
И ошибка, которую я получаю, такова:
Затем я отладил свой код и обнаружил, что процедура не входит в smileyHasValidNose
функцию. Тогда я не знаю причины.
Комментарии:
1. не совсем уверен, но я только что заметил, что большинство функций возвращают функцию, в то время как smileyHasValidNose выполняет
return smileyHasValidMouth(s)
вызов, возвращая значение, а не функцию.2. Что это за проблема, о которой вы упомянули? Я не знаком с этим и, следовательно, не знаком с тем, что пытается сделать ваш код. Я не смог бы знать, как это исправить или как использовать какие-либо потенциальные ответы здесь.
3. @VLAZ Проблема со смайликами -это проблема в кодовых войнах, и я хочу решить ее с помощью государственной машины.
4. Это информация, которая относится к вопросу . И не только ссылка — если содержание ссылки меняется или ссылка по какой-либо причине мертва, то вопрос теряет смысл. Я отредактировал вопрос, чтобы включить в него контекст. Пожалуйста, в будущем добавляйте всю соответствующую информацию в вопрос с самого начала.
Ответ №1:
Проблема в том, что вы на самом деле не переключаетесь state
между смайликами. Таким образом, следующим состоянием смайлика будет true
то, которое вы не можете вызвать (это не функция).
Вы можете использовать локальную переменную state
, которая сбрасывает ее в первую функцию (первый шаг).
Однако этот код приведет к ошибке, если в строке есть что-то еще, кроме смайлика (или его части).
Я бы изменил smileyHasValidMouth
, чтобы вернуться false
, если он не обнаружит смайлик. Просто чтобы быть более последовательным здесь…
И отрегулируйте свой цикл так, чтобы он выходил раньше, если он находит значение, которое не является функцией.
Комментарии:
1. Большое вам спасибо, вы решили мою проблему. Но другая проблема-это когда моя процедура тестирования массив [‘:~(‘, ‘:>’, ‘:Д’, ‘:(‘, ‘:О>’, ‘;)’, ‘:)’] он по-прежнему непойманные ошибку TypeError: государство не является функцией в консоли. Я отладил и обнаружил, что это происходит из-за того, что «:o>», второй и третий символы не совпадают. Но я уже давно не придумывал решения. Есть ли подход к ее решению?
2. @Ha0ran да, я изначально собирался написать второе предложение для решения этой проблемы, но я не знал, будет ли оно применимо к вашему делу.
3. @Ha0ran смотрите обновленный пост
4. Это оно. Еще раз спасибо!