Перезапуск цикла JavaScript for со значением, указанным в конце цикла for

#javascript #for-loop #code-injection

#javascript #цикл for #внедрение кода

Вопрос:

В настоящее время я пытаюсь создать средство проверки счастливых чисел, используя простой цикл for в javascript.

 function check(num){
    var sNum = String(num);
    var digits = [];
    while (num !== 1){
        for (var i = 0; i < String(num).length; i  ){
            digits.push(sNum.charAt(i));
            digits[i] = Number(digits[i] * digits[i]);          
        }
        num = eval(digits.join(' ')) 
        return num;
    }
    alert(num);
}
check(1);
  

Когда num получит свое значение после выхода из цикла, как бы мне повторно ввести новое значение num обратно в цикл for, чтобы начать процесс заново с новым num value . Если это можно решить с помощью того, что текущий цикл for оборачивается другим циклом вне его, как будет повторно введено новое значение num ? Спасибо вам всем!

Редактировать Вот обновленный код, в котором работает только число 1.

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

1. Создать из него функцию и вызвать ее снова с num в качестве параметра?

2. При выполнении этого будет return num; принято в качестве нового значения для параметра?

3. Избегайте использования eval в общем, почти всегда есть лучший способ сделать это. Вот один: function sum(numbers) { var result, i; result = 0; for (i = 0; i < numbers.length; i ) { result = numbers[i]; } return resu< }

4. Если вам не нужно поддерживать старые браузеры: digits.reduce(function (a, b) { return a b; }, 0);

Ответ №1:

Проверить наличие счастливого числа намного сложнее. Вы пишете цикл, который выполняется до тех пор, пока num не станет 1 . Ну, для несчастливых чисел num никогда не станет 1.

Вот код получше:

 function check(num) {
  var sNum,
      digits = [];
  var num;
  while (num !== 1) {
    // Add up all the digits
    sNum = num.toString();
    for (var i = 0; i < sNum.length;   i) {
      digits.push(( sNum[i]) * ( sNum[i]));
    }
    num = eval(digits.join(" "));
    // If num is 4, then the number will NEVER be happy
    if (num === 4) return false;
    // We must reset digits
    digits = [];
  }
  return true;
}
  

Это своего рода взлом. 4 это не единственное число, которое не является счастливым, но все несчастливые числа в конечном итоге пройдут через последовательность 4, 16, 37, 58, 89, 145, 42, 20 … (источник: Википедия), поэтому я проверяю 4 (хотя 20 или 16 подошли бы точно так же).

Кроме того, использование eval считается плохой практикой. Вместо этого используйте sum функцию, подобную:

 function sum(digits) {
  var s = 0;
  for (var i = 0; i < digits.length;   i) s  = digits[i];
  return s;
}
  

Затем вы можете заменить eval(digits.join(" ")) на sum(digits) .

Ответ №2:

Я думаю, это помогает:

 function isHappy(num) {
    if(num === 1) return true;
    if(num === 4) return false;
    return isHappy((num   '').split('').reduce(function(prev, digit) {
        return prev   digit*digit;
    }, 0));
}
  

Объяснение:

  1. Сначала мы проверяем, является ли число 1 , в качестве базового варианта для обнаружения счастливых чисел.
  2. Теперь у нас должен быть базовый вариант для обнаружения печальных чисел.

    Согласно Википедии, грустные числа заканчиваются в цикле 4, 16, 37, 58, 89, 145, 42, 20, 4, ... . Таким образом, мы можем проверить, например, 4 .

    Вы также могли бы проверить их все: ~[4, 16, 37, 58, 89, 145, 42, 20].indexOf(num) .

  3. Теперь мы выполняем рекурсивный вызов, чтобы проверить, является ли сумма квадратов цифр удовлетворительной.

    Чтобы вычислить эту сумму, мы используем:

    1. Сначала преобразуйте num в строку: num ''
    2. Затем разделите его на массив цифр.
    3. Наконец, мы reduce преобразовываем этот массив в сумму квадратов.

Ответ №3:

Потенциально вы могли бы вызвать функцию рекурсивно, если выполняется условие. Например:

 function check(num) {
    // your code, and then...
    if(/* whatever condition */) check(num);
}
  

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

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

1. Большое вам спасибо. Для новичка в разработке это бесценные знания, которые можно использовать повторно, за что я искренне благодарю вас. Существует ли термин для вызова функции внутри самой себя подобным образом?

2. Поскольку, если число не является счастливым, оно завершится в цикле 4, 16, 37, 58, 89, 145, 42, 20, 4, ... , не приведет ли ваш код к бесконечной рекурсии?

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

4. @Oriol, это зависит от условия, которое он предписывает. Я использовал num !== 1 только в качестве примера. Вместо этого он мог бы проверить, например, заканчивается ли число на 4, 16 или что-то еще, а затем рекурсивно вызвать функцию.

5. @Jking, термин для этого называется «рекурсивный вызов функции».