Приведение нуля через parseInt() в JS

Задачка которая принимает список неотрицательных целых чисел и строк и возвращает новый массив чисел.

const filterlist = [1, 2, "a", "b", 0];

function filter_list(l) {
  let arrayResult = [];
  for (const iteml of l) {
    if (parseInt(iteml)) {
      arrayResult.push(iteml);
    }
  }
  return arrayResult;
}

const res = filter_list(filterlist);

for (let i = 0; i < res.length; i++) {
  console.log(res[i]);
}

// console.log(parseInt(0));

При выполнении данного когда получается, что парсятся только 1 и 2, а 0 остаётся в пролёте, но почему тогда когда я в консоль привожу приведение (заккоментированная строка), то показывает, что это число. Я понимаю, что ноль ложное значение, но как обойти тогда?


Ответы (3 шт):

Автор решения: BlackStar1991

Причина, по которой в твоём предыдущем коде условие if (parseInt(iteml)) не сработало для 0, заключается в том, что в JS:

  • Число 0 считается ложным значением в контексте логических проверок.
  • Таким образом, в условии if (parseInt(0)), где результатом является 0, условие интерпретируется как false, и блок кода внутри if не выполняется.

Поэтому при проверке в if, когда результатом является 0, условие не проходит, несмотря на то, что parseInt(0) возвращает корректное число.

Просто так работает JS при интерпритации 0.

if (parseInt(0)) {
  console.log("Это истина");
} else {
  console.log("Это ложь");
}
// Выведет "Это ложь", потому что 0 интерпретируется как false

→ Ссылка
Автор решения: Grundy

Для обхода достаточно расширить условие дополнительной проверкой:

parseInt(iteml) || parseInt(iteml) == 0

В этом случае, при iteml === 0 будет дополнительно проверено второе условие.

→ Ссылка
Автор решения: Dev18

...по другому реализовать

'number' — это строка, возвращаемая оператором typeof, когда тип переменной или значения — число.

Проверка typeof item === 'number' позволяет узнать, является ли переменная числом, соответсвенно 0 туда тоже входит

=== в данном случае выполняет строгое сравнение, проверяя и тип, и значение.

const filterlist = [1, 2, "a", "b", 0];

function filter_list(l) {
  let arrayResult = [];
  for (const item of l) {
    if (typeof item === 'number') {
      arrayResult.push(item);
    }
  }
  return arrayResult;
}

const res = filter_list(filterlist);

for (let i = 0; i < res.length; i++) {
  console.log(res[i]);
}


но тут важно помнить, что NaN тоже число, поэтому можно добавить

if (typeof item === 'number' && !isNaN(item)) {
  //добавить проверку, что это также не NaN
}

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

if ((typeof item === 'number' && !isNaN(item)) || (!isNaN(parseFloat(item)) && isFinite(item)))

!isNaN(parseFloat(item)) проверяет, можно ли преобразовать строку в число, а isFinite() исключает бесконечные значения, такие как Infinity и -Infinity. Но помните, что parseFloat()/parseInt() может корректно преобразовывать строки, начинающиеся с чисел, даже если за ними следуют другие символы, и надо понимать оно нам надо, или как (например, 123bukvi=>123). Чтобы избежать таких случаев, можно использовать дополнительную проверку...

→ Ссылка