Як перетворити NaN з parseInt в 0 для порожнього рядка?


298

Чи можна якось повернути 0 замість того, NaNщоб розбирати значення в JavaScript?

У разі порожнього рядка parseIntповертається NaN.

Чи можливо зробити щось подібне в JavaScript для перевірки NaN?

var value = parseInt(tbb) == NaN ? 0 : parseInt(tbb)

А може, є інша функція або плагін jQuery, який може зробити щось подібне?


72
FYI , NaN != NaN. Вам знадобиться isNaN(value).
pimvdb

28
Так, жодні дві няні не однакові;)
Джеймс П.

3
Функція виклику parseInt()двічі (в успішному / нормальному NaNвипадку - ніколи) ніколи не є доброю ідеєю. Крім неефективності, для необережного, якщо все, що передається, tbbє функціональним викликом із побічними ефектами, це жахливо. Я б не використовував жодного рішення тут, де бачу parseInt()двічі.
JonBrave

Відповіді:


756
var s = '';

var num = parseInt(s) || 0;

Якщо не використовується з булевими значеннями, логічний ||оператор OR ( ) повертає перший вираз ( parseInt(s)), якщо його можна оцінити як істинне, інакше він повертає другий вираз (0). Повернене значення parseInt('')NaN. NaN оцінюється як false, тому в numкінцевому підсумку встановлюється 0.


6
Це не працюватиме, якщо s = "4s"; (повертається 4 ... що неправильно ...)
markzzz

1
parseInt функція в js
розбирає

26
@markzzz Прочитайте ще раз. ОП запитує: " Чи можна якось повернути 0 замість NaN ". ОП не хочу перевіряти, чи певна рядок є придатною до int. ОП хоче отримати 0замість NaN. Це ідеально вирішено кодом Метта.
trejder

2
@markzzzvar nextIphone = parseInt("4S") + 1; // wow it works!
Zero Distraction

2
@Matthew, будь ласка, використовуйте терміни "фальшивий" або "truthy" . тому що NaN === false - це неправда! але булева (NaN) === Булева (хибна) правда. логічний АБО повертає перший вираз, якщо його можна оцінити як "truthy"
Пабло Recalde

51

Ви також можете використовувати isNaN()функцію:

var s = ''
var num = isNaN(parseInt(s)) ? 0 : parseInt(s)

12
Навіщо дзвонити parseInt(s)двічі? Крім того, це повинно бутиparseInt(s, 10)
Dexygen

2
@GeorgeJempty За замовчуванням радіус "10"; цей параметр необов’язковий. parseInt()Хоча два рази дзвонити .
Осінній Леонард

8
@AutumnLeonard - це лише така правда. Якщо ваш рядок починається з 0, припускає, що число знаходиться у восьмеричному форматі, тож parseInt ('077') дає вам 63. Це може призвести до дуже неприємних пошуків помилок, тому вам слід завжди вказувати другий параметр. дивись, наприклад , stackoverflow.com/questions/8763396 / ...
chuck258

22

Я був здивований, не побачивши, щоб хтось згадував про використання Number(). Якщо це надано, він буде аналізувати десяткові знаки, якщо це передбачено, тому він буде діяти інакше, ніж parseInt(), однак він вже передбачає базу 10 і перетворить "" або навіть "" в 0.


1
Так, дуже зручно для читання з localStorage: Number (localStorage.getItem ('appBanner.count')) + 1
Philip Murphy

Хоча це працює на запитання так, як його задавали, він все ще повертає NaN для символів, що не мають пробілу без числа
Кайл Делані

9

Для людей, які не обмежені parseInt, ви можете використовувати оператор бітового АБО (який неявно викликає ToInt32його операнди).

var value = s | 0;

// NaN | 0     ==>> 0
// ''  | 0     ==>> 0
// '5' | 0     ==>> 5
// '33Ab' | 0  ==>> 0
// '0x23' | 0  ==>> 35
// 113 | 0     ==>> 113
// -12 | 0     ==>> -12
// 3.9 | 0     ==>> 3

Примітка: ToInt32відрізняється від parseInt. (тобто parseInt('33Ab') === 33)


Але: '10000000000' | 0 === 1410065408.
трінкот

@trincot так, будь-яке значення> = Math.pow(2, 31)переповниться.
Ахмад Ібрагім

8

Проблема

Інші відповіді не враховують, що 0є помилковим, і тому наступним буде 20 замість 0:

const myNumber = parseInt('0') || 20; // 20

Рішення

Я пропоную функцію помічника, яка вирішує більшість питань:

function getNumber({ value, defaultValue }) {
  const num = parseInt(value, 10);
  return isNaN(num) ? defaultValue : num;
}

Функція помічника дасть такі результати:

getNumber({ value: "0", defaultValue: 20 }); // 0
getNumber({ value: "2", defaultValue: 20 }); // 2
getNumber({ value: "2.2", defaultValue: 20 }); // 2
getNumber({ value: "any string", defaultValue: 20 }); // 20
getNumber({ value: undefined, defaultValue: 20 }); // 20
getNumber({ value: null, defaultValue: 20 }); // 20
getNumber({ value: NaN, defaultValue: 20 }); // 20
getNumber({ value: false, defaultValue: 20 }); // 20
getNumber({ value: true, defaultValue: 20 }); // 20

2
Будь ласка, надішліть radix на parseInt:, parseInt(string, radix)врахуйте це: parseInt("0x10") === 16Також parseInt("010")може поступатися 8у деяких браузерах
andlrc

2
Якщо ви вже залежать від лодашу для інших речей, є зручна defaultToфункція, яка робить саме це: _.defaultTo(NaN, -1)повертається -1, але _.defaultTo(0, -1);повертається 0.
waldyrious

Це відмінний момент! Ви можете покластися лише на || в кінці, щоб вказати правильний за замовчуванням, коли бажаним типовим параметром є ZERO (надано, це те, що хотіла ОП). Як ви вже згадували, через хибний характер вводу "0" в цьому випадку він вважається недійсним вводом, а виписка замість цього поверне значення за замовчуванням (можливо, не те, що очікувалося!)
JonathanDavidArndt

Напевно, вам слід використовувати const, а не дзвонити parseIntдвічі
Kyle Delaney

4

Чи є робота набагато чистішою, ніж аналіз на мою думку, скористайтеся оператором +

var s = '';
console.log(+s);

var s = '1024'
+s
1024

s = 0
+s
0

s = -1
+s
-1

s = 2.456
+s
2.456

s = ''
+s
0

s = 'wtf'
+s
NaN

1
Дуже компактний. Як прикро, що ти не отримав більше балів. Я проголосував за вас. Будь ласка, відповідь, щоб спробувати зловити моїх -2, придбаних сьогодні приглушеним тролем ... (див. Мою відповідь в кінці цієї сторінки). Дякую.
Фабієн Хаддаді


1

Зробіть окрему перевірку порожнього рядка (оскільки це один конкретний випадок) і встановіть його в нуль у цьому випадку.

Ви можете додати "0" до початку, але тоді вам потрібно додати префікс, щоб вказати, що це десятковий, а не вісімковий номер


тож ви вважаєте, що краще додати 0, якщо порожній?
Джопер

1
Ні - це я використовував підхід. У цьому випадку окрема перевірка була б кращою. Однак якщо рішення Матса працює, це ще чистіше.
Schroedingers Cat

1

Чому б не змінити функцію? У такому випадку ви завжди можете бути впевнені, що він повернеться 0у випадку NaN:

(function(original) {
    parseInt = function() {
        return original.apply(window, arguments) || 0;
    };
})(parseInt);

Тепер у будь-якому місці коду:

parseInt('') === 0

15
Перевиконання такої функції може збити з пантелику експертів-програмістів JavaScript, які можуть сприймати це як помилку. Ваша перекрита функція, ймовірно, буде похована десь там, де її, мабуть, не побачать. Це креативно, але я не впевнений, що я особисто рекомендував би це, враховуючи, як легко просто додати відповідь, || 0як у відповіді Метта. Я бачу, що переважаючі об'єкти, якими ви не володієте в крайньому випадку, або коли цього не робите, коштували б значно вище за часом та складністю.
jmort253

2
Я згоден з @ jmort253 ... Це небезпечно, оскільки функція занадто розумна. Краще виконувати точно таку ж функцію, але з такою назвою, як getSafeNumberValue або щось подібне.
Самуїл

1

У мене була подібна проблема (firefox v34) з простими рядками, такими як:

var myInt = parseInt("b4");

Тому я придумав швидкий злом:

var intVal = ("" + val).replace(/[^0-9]/gi, "");

А потім у всіх дурних складно розібратися з floats + ints для непростих речей:

var myval = "12.34";

function slowParseNumber(val, asInt){
    var ret = Number( ("" + val).replace(/[^0-9\.]/gi, "") );
    return asInt ? Math.floor(ret) : ret;
}
var floatVal = slowParseNumber(myval);

var intVal = slowParseNumber(myval, true);
console.log(floatVal, intVal);

Він поверне 0 для таких речей, як:

var intVal = slowParseNumber("b"); // yeilds 0

1
//////////////////////////////////////////////////////
function ToInt(x){x=parseInt(x);return isNaN(x)?0:x;}
//////////////////////////////////////////////////////
var x = ToInt('');   //->  x=0
    x = ToInt('abc') //->  x=0
    x = ToInt('0.1') //->  x=0
    x = ToInt('5.9') //->  x=5
    x = ToInt(5.9)   //->  x=5
    x = ToInt(5)     //->  x=5

Чи можете ви пояснити це рішення?
RamenChef

якщо ви хочете перетворити будь-яке число (наприклад, '123 'або 123) на ціле число, якщо ви будете використовувати parseInt (' abc '),
AbdulRahman AlShamiri

якщо ви будете використовувати parseInt ('abc'), ви
перейдете

Бінго як явна альтернатива ||підходу. Я знаю, що це давнє запитання та відповідь, але ця відповідь дозволяє уникнути виклику parseInt двічі і правильно використовує isNaN. Він просто потребує радіації, parseInt(x, 10)щоб бути ретельним. (Моя перевага - це окрема внутрішня змінна замість повторного використання x.)
goodeye

1

Я створив 2 прототипу, щоб вирішити це для мене, один для числа та один для String.

// This is a safety check to make sure the prototype is not already defined.
Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
        return this;
    }
};

// returns the int value or -1 by default if it fails
Number.method('tryParseInt', function (defaultValue) {
    return parseInt(this) == this ? parseInt(this) : (defaultValue === undefined ? -1 : defaultValue);
});

// returns the int value or -1 by default if it fails
String.method('tryParseInt', function (defaultValue) {
    return parseInt(this) == this ? parseInt(this) : (defaultValue === undefined ? -1 : defaultValue);
});

Якщо ви не хочете використовувати перевірку безпеки, використовуйте

String.prototype.tryParseInt = function(){
    /*Method body here*/
};
Number.prototype.tryParseInt = function(){
     /*Method body here*/
};

Приклад використання:

var test = 1;
console.log(test.tryParseInt()); // returns 1

var test2 = '1';
console.log(test2.tryParseInt()); // returns 1

var test3 = '1a';
console.log(test3.tryParseInt()); // returns -1 as that is the default

var test4 = '1a';
console.log(test4.tryParseInt(0));// returns 0, the specified default value

1
// implicit cast
var value = parseInt(tbb*1); // see original question

Пояснення для тих, хто не вважає це тривіальним:

Помножуючи на один, метод, який називається "неявна передача", намагається перетворити операнд невідомого типу в примітивний тип "число". Зокрема, порожній рядок стане номером 0, що робить його прийнятним типом для parseInt () ...

Дуже хороший приклад був також наведений вище PirateApp, який запропонував додати знак +, змусивши JavaScript використовувати анкетне число.


Це пряма відповідь на оригінальне запитання, мій дорогий.
Фабієн Хаддаді

Це не буде дляparseInt('str'*1)
Родіон Баскаков

Навіщо закликати parseIntщось, що вже є числом? Це призведе до чергового перетворення назад у рядок, щоб знову перетворити його на число.
trincot

0

Також таким чином, чому б не написати функцію і назвати її там, де це потрібно. Я припускаю, що це введення в поля форми для виконання розрахунків.

var Nanprocessor = function (entry) {
    if(entry=="NaN") {
        return 0;
    } else {
        return entry;
    }
}

 outputfield.value = Nanprocessor(x); 

// where x is a value that is collected from a from field
// i.e say x =parseInt(formfield1.value); 

що не так робити?


Привіт, Ват зупиняє нас від наступного вище методу. Хотіли б знати, щоб навчитися.
Нареш

3
Для тестування слід використовувати isNaNNaN .
Матвій

2
Дякую Метт :) Я не знаю, що в javascrip є функція під назвою isNaN ()! Дякую що дали мені знати...!
Нареш

0

Ось метод tryParseInt, який я використовую, це значення приймає за замовчуванням як другий параметр, тому воно може бути будь-чим, що вам потрібно.

function tryParseInt(str, defaultValue) {
    return parseInt(str) == str ? parseInt(str) : defaultValue;
}

tryParseInt("", 0);//0 
tryParseInt("string", 0);//0 
tryParseInt("558", 0);//558

0

допоміжна функція, яка все ще дозволяє використовувати радіакс

function parseIntWithFallback(s, fallback, radix) {
    var parsed = parseInt(s, radix);
    return isNaN(parsed) ? fallback : parsed;
}

0

Ви можете мати дуже чистий код, у мене були подібні проблеми, і я вирішив його, використовуючи:

var a="bcd";
~~parseInt(a);

0

Для інших людей, які шукають це рішення, просто використовуйте: ~~ без розбору, це найчистіший режим.

var a = 'hello';
var b = ~~a;

Якщо NaN, він натомість поверне 0.

ЗБМ. Це рішення стосується лише цілих чисел

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.