Цикл по строке слов, возвращает слово с наибольшим количеством баллов в соответствии со значением символа в Object — JavaScript

#javascript #arrays #string #object #increment

#javascript #массивы #строка #объект #увеличение

Вопрос:

Я пытаюсь выяснить, как решить эту ката в CodeWars.

Функция high получает строку и возвращает слово с наибольшим «количеством баллов», в соответствии с которым присутствуют буквы в слове. Буквы получают оценку в зависимости от их положения в алфавите. Итак a = 1 point, b = 2 points, c = 3 points , и так далее.

Я думаю, имеет смысл создать объект, в котором всем буквам алфавита присваивается значение:

Если буква в слове появляется в alphabetScore , это слово получит свои «баллы» и перейдет к следующей букве в слове, увеличивая общее количество баллов слова.

У меня есть:

 function high(string) {

  let words = string.split(" ");
  let wordScore = 0;

  const alphabetScore = {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    e: 5,
    f: 6,
    g: 7,
    h: 8,
    i: 9,
    j: 10,
    k: 11,
    l: 12,
    m: 13,
    n: 14,
    o: 15,
    p: 16,
    q: 17,
    r: 18,
    s: 19,
    t: 20,
    u: 21,
    v: 22,
    w: 23,
    x: 24,
    y: 25,
    z: 26
  }

  let word = words[i];
  let wordCount = 0;

  //loop through all words in the string

  for (let i = 0; i < words.length; i  ) {

    let word = words[i];

    //loop through all characters in each word

    for (let j = 0; j < word.length; j  ) {

      let value = alphabetScore[j];

      wordCount  = alphabetScore[value];

    }
  }
  return wordCount;
}

console.log(high("man i need a taxi up to ubud"));
  

И это возвращает ошибку, говорящую

i не определен

в let word = words[i] — как еще я мог бы определить слово, тогда?

Если возможно решить эту ката с помощью моей существующей логики (используя for-циклы), пожалуйста, сделайте это.

РЕДАКТИРОВАТЬ: изменено wordCount = alphabetScore.value ; на wordCount = alphabetScore[value];

РЕДАКТИРОВАТЬ 2: теперь возвращается NaN

ПРАВКА 3: последняя попытка:

 function myScore(input) {
    let key = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
    "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
    "w", "x", "y", "z"
    ];
    let bestWord = "";
    let bestScore = 0;
    let words = input.split(" ");
    for (let i = 0; i < words.length; i  ) {
      let score = 0;
      let word = words[i];
      for (let j = 0; j < word.length; j  ) {
        let char = word[j];
        score  = (key.indexOf(char)   1);
      }
      if (score > bestScore) {
        bestScore = score;
        bestWord = word;
      }
    }
    return bestWord;
  }
  

Ошибка ссылки: значение high не определено
в Test.describe._

Комментарии:

1. Почему бы вам просто не сохранить слово с наибольшим количеством баллов?

2. Хорошо — я не знаю, как выделить слово с наибольшим количеством баллов.

3.Вам нужно поместить ваше значение let word = words[i]; внутри вашего for-цикла, где i определено.

4. @StephenP определен word в первом цикле for, определен value во втором цикле for. Функция теперь возвращается NaN .

5. первое изменение if (score > bestScore) { bestScore = score; word = bestWord; } на if (score > bestScore) { bestScore = score; bestWord = word; }

Ответ №1:

успешно запущен в codewars

 let key = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
  "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
  "w", "x", "y", "z"
];

function wordScore(word) {
  let score = 0;
  for (let j = 0; j < word.length; j  ) {
    let char = word[j];
    score  = (key.indexOf(char)   1);
  }
  return score;
}

function high(x) {
  let bestWord = "";
  let bestScore = 0;
  words = x.split(" ");
  for (let i = 0; i < words.length; i  ) {
    let word = words[i];
    let score = wordScore(word);
    if (score > bestScore) {
      bestScore = score;
      bestWord = word;
    }
  }
  return bestWord;
}

console.log(high("man i need a taxi up to ubud"));  

Комментарии:

1. по какой-то причине работает в консоли, но не в Codewars

2. Да! Итак, что вы изменили? Вы объявили аргументы word и x ? Также не могли бы вы опубликовать решение перед рефакторингом?

3. изменено let bestWord; на let bestWord = ""; , чтобы значение undefined не возвращалось, если вводится пустая строка

4. Итак, если вы посмотрите на мою последнюю правку («последняя попытка» выше) — что в этом коде неверно по сравнению с тем, что вы только что сделали? Я вижу основное отличие в том, что вы создали вспомогательную функцию для каждого слова?

Ответ №2:

NaN означает «не число». Обычно это признак того, что вы пытались выполнить арифметику с нулем или чем-то еще в какой-то момент.

В этом случае ваш alphabetScore представляет собой хэш-карту букв, но вы ищете цифровые клавиши let value = alphabetScore[j]; : которые вернут undefined и undefined 0 == NaN . Вместо этого вам нужно сказать let value = alphabetScore[word[j]] — получить букву слова, а не индекс.

Чтобы сделать так, как предложил Джонас, создайте две новые переменные, где находится ваша первая let word = words[i] , и избавьтесь от нее, let highScore = 0; let highScoreWord = ""; чтобы сохранить самую высокую из найденных. Также переместите let wordCount = 0; внутри цикла. Теперь для каждого слова вы получите слово и сбросите количество.

Наконец, после внутреннего цикла, скажем, if (wordCount > highScore) { highScore = wordCount; highScoreWord = word; } . Поэтому, если оно выше вашего текущего максимального значения, сохраните его; в противном случае просто игнорируйте его.

Тогда return highScoreWord и вы должны быть золотыми!