Что вам следует изучить:

  • Как разбить проблему на более мелкие целенаправленные части.
    * Используйте функции, чтобы разбить задачу на части, которые можно использовать повторно, вместо того, чтобы повторяться.
  • Координация взаимодействия в рамках многоразовой функции.
    * Когда две или более функций должны иметь доступ к разным частям другой функции.
  • Вариант использования объекта и массива.
    * Сопоставление ключей со значениями в объекте и обеспечение порядка с помощью массива.

ВОПРОС 1
Напишите функцию с именем «convertFahrToCelsius», которая принимает единственный параметр и преобразует его в градусы Цельсия.
Если переданный параметр не является число или строку, которые могут быть преобразованы в допустимое число, вернуть строку в следующем формате:
`$ {параметр} не является допустимым числом, а / является $ {типом параметра}. `

Вот мое решение:

// Main function
function convertFahrToCelsius(fahr) {  
  const fahrType = getType(fahr);  
  const isValidType = validateType(fahrType, fahr);  
  if (isValidType) {    
    const fahrenheit = Number(fahr);    
    return Number(((fahrenheit - 32) * (5 / 9)).toFixed(4));  
  }  
  return errorMessage(fahr, fahrType);
}
convertFahrToCelsius({yes:1,no:0})

Приведенная выше функция принимает параметр и проверяет, является ли параметр допустимым типом, то есть числом или строкой, которые можно преобразовать в допустимое число . Если это допустимый тип, мы переходим к преобразованию в градусы Цельсия, в противном случае мы возвращаем сообщение об ошибке.

Тип поиска
Сначала мы определяем тип параметра с помощью функции getType , а затем присваиваем возвращаемое значение fahrType [строка 3, основная функция] .
Я подумывал об использовании typeof, но думал, что это приведет к множеству заявлений типа «если». Затем узнал о Array.isArray, но я не уверен, что такие же выходы для других встроенных объектов. typeof value не даст соответствующего результата для Array, Set, RegExp, Date, Function или Error. Все они уступят Object. Теперь я начал изучать JavaScript, используя книгу Кайла Симпсона «Вы не знаете Js» и обнаружил, что некоторые значения, скажем так, являются «внутренне классифицированными», и эту классификацию можно раскрыть - "[object typeOfObject]" - позвонив Object.prototype.toString(..) против их.

Object.prototype.toString("lmn")          // "[object String]"
Object.prototype.toString(123)            // "[object Number]"
Object.prototype.toString(true)           // "[object Boolean]" Object.prototype.toString(null)           // "[object Null]"
Object.prototype.toString(new Set())      // "[object Set]"

Не будем обращать внимания на нюансы того, как работает Object.prototype.toString(..).
Осталось только извлечь соответствующую часть возвращенной строки с помощью метода substring(..). substring принимает два целых числа (которые обозначают начальную и конечную позицию) и возвращает часть строки между начальным и конечным индексами. Преобразуем извлеченную строку в нижний регистр и возвращаем.

function getType(fahrValue) {  
  const internalType = Object.prototype.toString.call(fahrValue);
  const extractedType = internalType
     .substring(8, internalType.length - 1)
     .toLowerCase();  
return extractedType;
}

Теперь мы можем получить подходящий тип любого значения.

Подтвердить тип
Затем нам нужно проверить тип. Нам нужны только значения типа «число» или «строка», которые можно преобразовать в действительное число. Обратите внимание, что typeof NaN возвращает «число».

function validateType(fahrType, fahrValue) {  
  if (fahrType === "number" || (fahrType === "string" && fahrValue.trim().length > 0 && !isNaN(Number(fahrValue)))) {       
  return true;  
  }  
return false;
}

Функция validateType принимает значение и его тип, возвращает true, если тип допустим, elsefalse. Возвращаемое значение присваивается isValidType [строка 4-основная функция].
Это выглядит следующим образом: если тип является числом или строкой, но не просто строкой, не пустой строкой и строкой, содержимое которой может быть преобразовано в допустимое число - верните true. В противном случае верните false.
Возможно, вам потребуется прочитать об операторах- ||, &&,! - их приоритете и о том, как обеспечить привязку к оператору с помощью круглых скобок.

Теперь
Вот наша основная функция. Мы извлекли тип параметра, а также проверили его.

// Main function
function convertFahrToCelsius(fahr) {  
  const fahrType = getType(fahr);  
  const isValidType = validateType(fahrType, fahr);  
  if (isValidType) {    
    const fahrenheit = Number(fahr);    
    return Number(((fahrenheit - 32) * (5 / 9)).toFixed(4));  
  }  
  return errorMessage(fahr, fahrType);
}
convertFahrToCelsius({yes:1,no:0})

isValidType может быть true или false в зависимости от значения, возвращаемого validateType. Если это правда, мы преобразуем наше значение в число, если это строка, и присваиваем значение fahrenheit. (fahrenheit — 32) * (5 / 9) выполняет наше преобразование, мы округляем до 4 десятичных знаков, используя toFixed(4). Обратите внимание, что toFixed возвращает строку. Наконец, мы конвертируем строку обратно в число - Number(..).
Если validateType равно false, мы просто возвращаем сообщение об ошибке errorMessage(fahr, fahrType).

Сообщение об ошибке

function errorMessage(inputValue, inputValueType) {  
  const inputValueString = JSON.stringify(inputValue);  
  if (inputValueType !== null) {    
    return `${inputValueString} is not a valid number but a/an ${inputValueType}`;
  }  
  return `invalid parameter : ${inputValueString}`;
}

Функция errorMessage принимает значение и его тип, преобразует значение в строку (используя JSON.stringify) и возвращает литерал шаблона.
У нас есть два оператора возврата, по одному для каждого вопроса, и условие , которое помогает нам решить, какое из них будет выполнено. (inputValueType !== null) можно рассматривать как ворота, а inputValueType - его ключ. Значение inputValueType помогает решить, какой раздел кода «разблокировать» (или выполнить). Первый оператор return всегда будет выполняться для текущего вопроса, поскольку inputValueType всегда не будет значением null (это всегда строка - «объект», «массив», «ноль» и т. Д.). В то время как второй оператор return всегда будет выполняться для вопроса 2, поскольку inputValueType всегда будет null.

ВОПРОС 2
Напишите функцию с именем «checkYuGiOh», которая принимает число n в качестве аргумента, создает массив чисел от 1 до n и заменяет числа, кратные 2, 3. , и 5 с «yu», «gi» и «oh», затем возвращает результирующий массив.
Выполните проверку введенных данных и return ` недопустимый параметр: $ {parameter} ` если недопустимый параметр

Решение:

//Main function
function checkYuGiOh(inputParam) {  
  const paramType = getType(inputParam);  
  const isValidType = validateType(paramType, inputParam);  
  if (isValidType) {    
    const inputNumber = Number(inputParam);    
    const arr = [];    
    for (let n= 1; n<= inputNumber; n++) {
      let accumulatedString = accumulator(n);      
      if (isEmptyString(accumulatedString, null)) {        
        arr.push(n);      
      } else {        
        arr.push(accumulatedString);      
      }    
    }    
    return arr;  
  }  
  return errorMessage(inputParam, null);
} 
checkYuGiOh(30);

Мы из строки 5, поскольку в этом вопросе также используются те же функции, что и в вопросе 1, для определения и проверки типа. Если тип является допустимым типом, мы используем значение для создания элементов для заполнения выходного массива. Если тип недействителен, мы генерируем сообщение об ошибке, используя ту же функцию сообщения об ошибке, что и в вопросе 1, за исключением того, что на этот раз мы передаем null как inputValueType, поэтому выполняется только второй оператор возврата.

Давайте поговорим подробнее о том, допустим ли это тип и как мы генерируем элемент для выходного массива.

Выходной массив
Выходной массив должен содержать n элементов, поэтому мы выполняем итерацию n раз, начиная с 1. На каждой n-й итерации мы проверяем, является ли 2,3,5 кратным текущему значению n. затем мы соответствующим образом объединяем (с помощью «yu», «gi» или «-gi», «oh» или «-oh»), генерируя строку для n-й позиции в нашем выходном массиве. Скажем, n = 5, тогда n-е значения - 1, 2, 3,4, 5.

Чтобы сгенерировать строку для позиции в выходном массиве, мы используем функцию isEmptyString для фактического объединения, в то время как функция accumulator удерживает текущее / обновленное состояние строки, которую мы создаем, а также возвращает окончательный результат. строка, присвоенная accumulatedString [строка 9 - основная функция].
Обратите внимание, что выходной массив не имеет нулевого индекса, поскольку n-й элемент хранится в n-й позиции.

Функция накопителя

function accumulator(n) {  
  const table = { yu: 2, gi: 3, oh: 5 };  
  const stringsTojoin = ["yu", "gi", "oh"];  
  let stringAccumulator = "";  
  for (let stringValue of stringsTojoin) {    
    if (n % table[stringValue] === 0) {      
      stringAccumulator = isEmptyString(stringAccumulator, stringValue);    
    }  
  }  
  return stringAccumulator;
}

Функция аккумулятора принимает целое число (текущее n-е значение) в качестве параметра, проверяет, является ли 2, 3 или 5 кратным этому целому числу, затем строит строку соответственно с помощью «yu», «gi» или «-gi», «Ой» или «-ох».

Сначала у нас есть переменная table, ссылающаяся на объект, ключи / строковые значения которого сопоставлены с соответствующими целочисленными значениями и также являются элементами массива stringTojoin. Обратите внимание на порядок элементов / строк в массиве stringToJoin. ПеременнаяstringAccumulator содержит текущее состояние строки, которую мы собираемся построить и вернуть для позиции в выходном массиве.

Мы повторяем массив stringTojoin для каждого элемента / строки, выполняем «ключевой доступ» table[stringValue], чтобы получить соответствующее целочисленное значение, затем проверяем, кратно ли оно текущему n-му значению, переданному в accumulator функции. Если оно кратное, мы строим строку в функцииisEmptyString, передавая текущее состояние нашей строки- stringAccumulator -и соответствующее 'stringValue' ( «yu», «gi», «oh» ) для конкатенации, затем переназначьте stringAccumulator «обновленное состояние» или вновь созданную строку, возвращаемую функцией isEmptyString [строка 7, accumulator функция].
После итерации массива stringTojoin и построения строки мы возвращаем окончательное состояние нашей строки, хранящейся в переменной stringAccumulator. Накопленная строка затем помещается в n-ю позицию в нашем выходном массиве.

isEmptyString F функция - Как мы строим строку

function isEmptyString(stringHolder, stringValue) {  
  const lengthOfStringHolder = stringHolder.length;  
  if (stringValue !== null) {    
    if (lengthOfStringHolder !== 0) {      
      stringHolder += "-";    
    }    
    return stringHolder + stringValue;  
  }  
  return lengthOfStringHolder === 0 ? true : false;
}

Функция isEmptyString выполняет фактическое накопление, построение или конкатенацию и возвращает вновь сформированную строку. Он принимает в качестве параметра текущее состояние строки - stringHolder (stringAccumulator) - и 'stringValue' (соответственно «yu», «gi» или «oh»), объединяет их stringHolder + stringValue и возвращает новую сформированную строку. Нам нужно только проверить, является ли состояние stringHolder пустым или не пустым-(lengthOfStringHolder !== 0)-, чтобы знать, должны ли мы конкатенировать дефис (-) или нет.

Между тем,
В функции Main [строка 10] функция isEmptyString также помогает определить, является ли последняя строка (возвращенная функцией accumulator для n-й позиции в выходном массиве) пуста или нет, чтобы решить либо отправить n-е значение (если сгенерированная строка пуста), либо отправить сгенерированную строку в наш выходной массив.

// from Main function
...
if (isEmptyString(accumulatedString, null)) {        
        arr.push(n);      
} else {        
    arr.push(accumulatedString);      
}
...

Мы используем тот же метод, что и функция сообщения об ошибке, чтобы решить, какую часть функции isEmptyString выполнять. Мы вызываем isEmptyString функцию с null в качестве второго аргумента-isEmptyString(accumulatedString, null). Если stringValue равно null [строка 3 isEmptyString функция], мы возвращаемся, выполняем второй оператор возврата return lengthOfStringHolder === 0 ? true : false [строка 9, isEmptyString функция]. Он возвращает true, если последняя строка пуста еще false.

.. в конце концов, я получил высшую оценку, но мне мягко напомнили, что это не идеальное решение.
- Стори-алгоритм, Frontend Task 4

Вы должны улучшить это, если можете.

Пожалуйста, дайте ему несколько хлопков. Это бесплатно для вас, но для меня очень много значит. 😊

Полный код на github: посмотреть код