@StepanMogilyov

В чём ошибка в задаче?

Добрый день. Укажите пожалуйста на мою ошибку.
Задача:
Напишите функцию, которая проверит, являются ли два заданных символа одним и тем же регистром.

Если какой-либо из символов не является буквой, верните -1
Если оба символа имеют одинаковый регистр, верните 1
Если оба символа являются буквами, но не в одном регистре, верните 0
function sameCase(arg1, arg2) {
  let counter = 0
  if (arg1 || arg2 != '') {  //Если какой-либо из символов не является строкой, пытаюсь вернуть -1
    counter -= 1
  } else if (arg1.toLowerCase() && arg2.toLowerCase() || arg1.toUpperCase() && arg2.toUpperCase()) { //Если оба символа имеют одинаковый регистр, пытаюсь вернуть 1
    counter += 1
   } else if (arg1 && arg2 == '' && arg1 !== arg2) { //Если оба символа являются буквами, но не в одном регистре, пытаюсь вернуть 0
    counter = 0
   }
  return counter
}

console.log(sameCase('G', 'f'))
  • Вопрос задан
  • 286 просмотров
Пригласить эксперта
Ответы на вопрос 3
sergiks
@sergiks Куратор тега JavaScript
♬♬
Три подсказки.

Проверить, что аргумент является строкой:
typeof arg === 'string'
// ещё можно длину проверить, а то, вдруг длинное пришлют
arg.length === 1

Проверить, что это буква и есть пара в другом регистре:
arg.toLowerCase() !== arg.toUpperCase()
// строка перевелась в разные кейсы

В каком кейсе изначально была буква:
arg.toUpperCase() === arg // значит, буква в верхнем регистре


Из этих кирпичиков остаётся сложить домик. И чтоб не рухнул )
Ответ написан
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Без ошибок тут только заголовок функции.
Причём, ошибки как семантические - неверные формулировки условий, так и логические - условия неверны в принципе.
Ответ написан
Комментировать
dollar
@dollar
Делай добро и бросай его в воду.
Нельзя писать arg1 || arg2 != '', подобно кальке с русского языка.
В программировании всё последовательно:
  • Либо сначала считает !=, а этот операнд имеет приоритет, поэтому если без скобок, то это эквивалентно такому: arg1 || (arg2 != ''). В этом случае мы проверяем, что arg2 не является пустой строкой. При этом он может быть символом или числом, например. ИЛИ arg1 является истинным.
  • Либо сначала считает ||, если иначе расставить скобки: (arg1 || arg2) != ''. В этом случае тоже ерунда какая-то. Мы проверяем истинность хотя бы одного аргумента, а потом зачем-то результат операции сравниваем с пустой строкой.


Чтобы составить условие правильно, его нужно структурировать для понимания, то есть составление как бы разбить на этапы.
  1. Сначала нужно понять, как сформулировать простое условие "не является буквой". Условно запишем по-русски.
  2. Далее составляем следующее более сложное условие из кирпичиков, полученных на предыдущем этапе: (arg1 является буквой) && (arg2 является буквой). То есть для каждого аргумента повторяем выражение полностью. Если сомневаетесь в приоритетах вычислений, можно ещё и скобки расставить.


Но вернёмся к началу. Вроде бы простое условие "arg является буковой", но готовой функции у нас нет. И чтобы проверить это утверждение, нужно проверить ещё более простые:
1) что arg является строкой в принципе (не числом, не булевой переменной, не всякими там null и пр.)
2) что эта строка имеет длину 1. Ведь если больше 1, то это уже не просто буква. А если меньше, то есть 0, то это тем более не буква.
3) что оставшийся символ действительно является буквой. Не прибегая к регулярным выражениям (что для вас будет явно сложно), я бы схитрил так:
arg==arg.toLowerCase() || arg==arg.toUpperCase()
Обратите внимание на порядок операций. Сначала считаются сравнения, а потом они складываются через логическую операцию ИЛИ. То есть, если по-русски, мы записали, что символ равен самому себе в верхнем регистре, либо он равен самому себе в нижнем регистре. Это и будет означать, что это буква.

Если же опустить предыдущие проверки, и допустить, например, что это длинная строка, например "абвгд", то у нас последнее утверждение окажется ошибочно верным, так что сначала нужно исключить всё лишнее.

Ещё один совет: не обязательно городить бесконечный if else. Конечно, так тоже можно, но получается более громоздко и менее очевидно. Проще писать серию return'ов. Это всегда проще, а в вашем примере сам бог велел так делать. Пример:
if (typeof arg1 != "string") return -1;
if (arg1.length != 1) return -1;
//и т.д.

Здесь мы первой проверкой исключаем возможность, что это не строка. То есть если это не строка, то дальше выполнение функции не происходит, и мы сразу выходим. Поэтому во второй проверке уже можно быть точно уверенным, что arg1 - это строка, и исходить из этого. И весь код ниже тоже может рассчитывать, что arg1 - это строка длиной 1 символ, без вариантов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы