Принимая строку и обращая определенные слова - Javascript - PullRequest
0 голосов
/ 31 декабря 2018

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

Код, который я написал, переворачивает всю строку.Я полагаю, что это что-то с оператором if, оно не перехватывает слова больше 5. При написании кода я думаю сначала преобразовать строку в массив слов, использовать цикл for для запуска массивов и найти словакоторые больше 5, затем поменяйте местами слова больше 5. Я обнаружил похожие проблемы, и вот как далеко я добился помощи.Я застрял, любая помощь будет принята с благодарностью!Я новичок в кодировании и изучении Javascript.

function spinWords(backward){

 var sentence = "";
 var separate = backward.split("");

 for (var i = separate.length - 1; i >= 0; i--){
   if (separate[i].length >= 1){
   sentence += separate[i].split("").reverse().join("");
   }
  else {
  sentence += "" + separate[i];
  }
 }
return sentence;
}

spinWords("Hey fellow warriors");

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

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


Breakingпроблема вниз

Вы хотите сделать несколько вещей здесь, так что это может помочь разбить проблему на этапы.

По сути, вы хотите обратить вспять определенные слова.Так почему бы не написать функцию, которая делает только это?Это должно быть просто.Вот одна из версий:

const reverseWord = word => word.split('').reverse().join('')
reverseWord('word') //=> 'drow'

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

const reverseIfGte5 = word => word.length >= 5 ? reverseWord(word) : word
reverseIfGte5('word') //=> 'word'
reverseIfGte5('supercalifragilisticexpialidocious')
//=> 'suoicodilaipxecitsiligarfilacrepus')

Обратите внимание, что здесь мы пишем reverseIfGte5 , используя reverseWord.Таким образом, наша функция reverseWord также доступна для повторного использования, если мы выберем, но также и для того, чтобы каждая функция выполняла что-то простое.

Теперь мы можем написать spinWord в терминах этой функции через

const spinWords = sentence => sentence.split(/\s+/).map(reverseIfGte5).join(' ')

spinWords('Hey fellow warriors') //=> 'Hey wollef sroirraw'

Это делает то, что ожидается.И это может быть хорошим местом для остановки.Однако ...

Делать только одну вещь для функции

Наша функция spinWords, указанная выше, отвечает за две вещи:

  • поиск слов в предложении
  • применяя нашу функцию реверса к каждому

В идеале, функция должна отвечать только за одно, а за одно.(Конечно, при принятии решения о том, как такие обязанности распадаются, необходимо принять определенное решение.)

Возможно, было бы полезно разорвать это на части.Мы можем сделать это по-разному.Вот простой пример:

const updateWords = wordFn => sentence => sentence.split(/\s+/).map(wordFn).join(' ')
const spinWords = updateWords(reverseIfGte5)

Теперь у нас есть функция многократного использования, которую мы могли бы использовать, например, с очевидной функцией capitalizeFirstLetter, подобной этой:

const titleCase = updateWords(capitalizeFirstLetter)
titleCase('Hey fellow warriors') //=> 'Hey Fellow Warriors')

Исправление ошибок

Наш код теперь выглядит следующим образом:

const updateWords = wordFn => sentence => sentence.split(/\s+/).map(wordFn).join(' ')
const reverseWord = word => word.split('').reverse().join('')
const reverseIfGte5 = word => word.length >= 5 ? reverseWord(word) : word
const spinWords = updateWords(reverseIfGte5)

Эти функции упорядочены от наиболее вероятных к наименее вероятным для повторного использования.

Обратите внимание, что общий код здесьпри использовании таких многократно используемых функций немного длиннее этой простой версии:

const spinWords = sentence => sentence.split(/\s+/).map(
  word => word.length >= 5 ? word.split('').reverse().join('') : word
).join(' ')

Но наша версия имеет несколько преимуществ.Очевидно, что возможность повторного использования одна.Но другая проблема заключается в том, что, если проблема будет разбита на мелкие кусочки, если мы найдем проблему, мы знаем, где искать решение.

И угадайте, что в этом решении действительно есть потенциальная ошибка.

Если мы вызываем эту функцию с 'Hey fellow warriors', мы возвращаем 'Hey wollef oirraw' вместо ожидаемого 'Hey wollef sroirraw'.Наш интервал отключен.

Поскольку эта проблема разбита на отдельные функции, не возникает вопроса о том, какую функцию нам нужно изменить, чтобы исправить это.Ясно, что именно эта функция отвечает за разделение и соединение предложения updateWords.Есть одно простое исправление: изменение с

const updateWords = wordFn => sentence => sentence.split(/\s+/).map(wordFn).join(' ')

на

const updateWords = wordFn => sentence => sentence.split(' ').map(wordFn).join(' ')

, но нам может быть лучше использовать вариант ответа от CertainPerformance и переписать его так:

const updateWords = wordFn => sentence => sentence.replace(/\w+/g, wordFn)

Это исправляет ошибку и фактически обрабатывает больше случаев, чем мы могли бы изначально.(Обратите внимание, что теперь он также работает с символами пунктуации):

spinWords('Hey, fellow warriors!') //=> 'Hey, wollef sroirraw!'

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

Рабочий код

Вот к чему мы пришли:

const updateWords = wordFn => sentence => sentence.replace(/\w+/g, wordFn)
const reverseWord = word => word.split('').reverse().join('')
const reverseIfGte5 = word => word.length >= 5 ? reverseWord(word) : word

const spinWords = updateWords(reverseIfGte5)

console.log(spinWords('Hey, fellow warriors!'))

Мы разбили проблему на две довольно многократно используемые функции (reverseWord и updateWords) и две, очень специфичные для нашей проблемы (reverseIfGte5 и * 1093).*.) Каждый из них имеет четко определенную ответственность, и его легко проверить в изоляции.

Расширение в дальнейшем

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

const when = (cond, then) => val => cond(val) ? then(val) : val
const reverseIfGte5 = when(word => word.length >= 5, reverseWord)

Я создал when, потому что естьвремена, когда я хочу использовать измененную версию своего ввода, если какое-то условие верно для него, и использовать его без изменений, если условие ложно.Это именно то, что нужно reverseIfGte5, поэтому полезно построить его поверх when.

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

Я один из авторов Ramda , служебной библиотеки для функционального программированияв JS, и именно так оно и было построено.

0 голосов
/ 31 декабря 2018

Вы могли бы найти логику намного проще, если бы вы использовали регулярное выражение для сопоставления 5 или более символов слова в строке и использовали функцию замены для reverse их:

function spinWords(backward) {
  return backward.replace(/\w{5,}/g, word => word.split('').reverse().join(''));
}

console.log(spinWords("Hey fellow warriors"));

Чтобы исправить свой код, вы должны разделить входную строку (переменную с именем backward) на пробел , а не на пустую строку,чтобы получить массив слов, затем выполнить итерацию по этому массиву (начиная с начала, а не в конце), проверяя для каждого слова length и конкатенируя с sentence:

function spinWords(backward) {

  var sentence = "";
  var separate = backward.split(" ");
  
  for (var i = 0; i < separate.length; i++) {
    if (sentence) sentence += ' ';
    if (separate[i].length >= 5) {
      sentence += separate[i].split("").reverse().join("");
    } else {
      sentence += separate[i];
    }
  }
  return sentence;
}

console.log(spinWords("Hey fellow warriors"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...