Почему цикл for останавливается на первой итерации?

#javascript #for-loop

#javascript #for-цикл

Вопрос:

Я хочу найти самое длинное слово в массиве, используя цикл for . Но итерация останавливается на первом проходе. Чего мне не хватает?

 var a = "hello asdf asdf sdfgfghkkjb";
var s = a.split(" ");
var m = -Infinity;
for (var i = 0; i < s.length; i  ) {
  if (s[i].length > m) {
    m = s[i];
  }
}
console.log(m)  

Ответ №1:

В этом if-операторе вы сравниваете длину слова с самим словом : if (s[i].length > m) . Измените его, чтобы сравнить длины обоих слов: if (s[i].length > m.length) и установите начальное значение m на как можно более короткое «слово», например var m = "" .

 var a = "hello asdf asdf sdfgfghkkjb";
var s = a.split(" ");
var m = "";
for (var i = 0; i < s.length; i  ) {
  if (s[i].length > m.length) {
    m = s[i];
  }
}
console.log(m)  

Ответ №2:

Для достижения ожидаемого результата используйте приведенную ниже опцию сортировки по длине каждого слова

  1. Разделить строку пробелом
  2. Сортировка массивов слов по убыванию длины
  3. Выберите первый элемент для самого длинного слова

 var a = "hello asdf asdf sdfgfghkkjb";
var s = a.split(" ").sort((a,b) => b.length - a.length)[0]

console.log (s)  

codepen — https://codepen.io/nagasai/pen/KYymjd?editors=1010

Вариант 2: используя метод reduce, выполните цикл по массиву один раз и верните самое длинное слово

 var a = "hello asdf asdf sdfgfghkkjb";
var s = a.split(" ").reduce((acc, v) => {
  acc = v.length > acc.length ? v : acc;
  return acc
}, '')

console.log (s)  

codepen — https://codepen.io/nagasai/pen/xePrgj?editors=1010

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

1. Хотя это явно будет работать, концептуально это излишне, O(n*log(n)) алгоритм (или даже в O(n^2) зависимости от метода сортировки), когда O(n) достаточно.

2. Спасибо @JohnColeman, обновил мой ответ вариантом 2, используя метод уменьшения, а также с лучшей временной сложностью O (n)

3. Я думаю, что reduce — это правильный путь. 1

Ответ №3:

Вы сравниваете слова с числами:

 var s = a.split(" ");
var m = -Infinity; // m is a number
for (var i = 0; i < s.length; i  ) {
   if (s[i].length > m) { // in first iteration, true, 5 > -Infinity
      m = s[i]; // in first iteration, m becomes a word
   }
}
  

… в последующих итерациях у вас будут сравнения типа «4> привет».

Ответ №4:

потому что первая итерация if(s[i].длина> m) имеет m = -бесконечность. затем вы повторно присваиваете значение m внутри блока if, поэтому на следующей итерации вы проверяете, является ли s [i].длина больше, чем «привет»

Ответ №5:

На итерации тест выполнен успешно, поэтому вы:

 m = s[i];
  

что эквивалентно:

 m = "hello";
  

На второй итерации вы тестируете:

 if (s[i].length > m)
  

что эквивалентно:

 if (4 > "hello")
  

Поскольку вы сравниваете объекты разных типов, он преобразует их в общий тип; в этом случае он пытается преобразовать строку в число. Поскольку строка не является числовой, она преобразуется в NaN , и любое сравнение с NaN всегда возвращается false .

Вам нужны две переменные, одна для текущей максимальной длины, а другая для самой длинной строки.

 var a = "hello asdf asdf sdfgfghkkjb";
var s = a.split(" ");
var m = -Infinity; // maximum length
var ms; // longest string
for (var i = 0; i < s.length; i  ) {
  if (s[i].length > m) {
    ms = s[i];
    m = ms.length;
  }
}
console.log(ms)  

Ответ №6:

Вам нужны отдельные переменные для хранения длины самой длинной строки и текущей строки.

 var a = "hello asdf asdf sdfgfghkkjb";
var s = a.split(" ");
var m = -Infinity;
var longest = '';

for (var i = 0; i < s.length; i  ) {
  if (s[i].length > m) {
    longest = s[i];
    m = s[i].length;
  }
}
console.log(longest)