Почему я могу пройти через массив, но не вверх - Javascript - PullRequest
0 голосов
/ 24 августа 2018

Может кто-нибудь объяснить, почему это не работает:

function filterNumbers(arr) {

  for (var i = 0; i < arr.length; i++) {
    if(typeof arr[i] !== 'number') {
      arr.splice(i, 1);
    }
  }
}

Но это так:

function filterNumbers(arr) {

  for (var i = arr.length - 1; i >= 0; i--) {
    if (typeof arr[i] !== 'number') {
      arr.splice(i, 1);
    }
  }
}

Мне кажется, что функциональность идентична, я не могу понять, что такое фалуер.

Массив ввода, с которым я тестирую:

var arr = [1, 'a', 'b', 2];

Ответы [ 3 ]

0 голосов
/ 24 августа 2018

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

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

function isNumber(obj) {
  return obj !== undefined && typeof(obj) === 'number' && !isNaN(obj);
}

var newArr = arr.filter(isNumber);
0 голосов
/ 24 августа 2018

Каждый не отвечает прямо на ваш вопрос и продолжает ссылаться на длину.

Ваш код:

function filterNumbers(arr) {

     for (var i = 0; i < arr.length; i++) {
         if(typeof arr[i] !== 'number') {
            arr.splice(i, 1);
         }
     }
}

Проблема в том, на что i ссылается (что играет роль с длиной, но они не объясняют дальше). Когда i равен 1, вы ссылаетесь на a вашего массива. Затем вы склеиваете его из массива, который теперь делает 1 ссылку «b». Это все еще в цикле for до завершения его итерации. Затем вы увеличиваете i с 1 (который ссылается на b сейчас) до 2, который затем ссылается на 2 в вашем массиве.

Вы можете проверить это дальше, сделав в вашем массиве все буквы, и вы увидите, как пропустите все остальные буквы (['a', 'b', 'c', 'd', 'e', 'f'] приведет к ['b', 'd', 'f']).

Чтобы обойти проблему, вам придется увеличить / уменьшить i в зависимости от того, что вы делаете внутри цикла. Если вы склеиваете, уменьшаете i или добавляете оператор else в цикле и увеличиваете значение i внутри оператора else, а не после каждой итерации.

0 голосов
/ 24 августа 2018

Длина массива меняется с каждым циклом, поэтому возникает проблема.

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

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