Jak zmienić NaN z parseInt na 0 dla pustego ciągu?


298

Czy możliwe jest jakoś zwrócić 0 zamiast NaNpodczas analizowania wartości w JavaScript?

W przypadku pustego ciągu parseIntzwraca NaN.

Czy w JavaScript można zrobić coś takiego NaN?

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

A może istnieje inna funkcja lub wtyczka jQuery, która może zrobić coś podobnego?


72
FYI, NaN != NaN. Że trzeba isNaN(value).
pimvdb

28
Tak, nie ma dwóch takich samych opiekunów;)
James P.,

3
parseInt()Dwukrotne wywołanie funkcji (w udanym / normalnym NaNprzypadku innym niż przypadku) nigdy nie jest dobrym pomysłem. Poza nieefektywnością, dla nieostrożnych, jeśli cokolwiek zostanie pominięte, tbbjest wywołanie funkcji z efektami ubocznymi, jest straszne. Nie użyłbym tutaj żadnego rozwiązania, w którym widzę parseInt()dwa razy.
JonBrave

Odpowiedzi:


756
var s = '';

var num = parseInt(s) || 0;

Gdy nie jest używany z wartościami logicznymi, ||operator logiczny OR ( ) zwraca pierwsze wyrażenie ( parseInt(s)), jeśli można je oszacować jako prawda, w przeciwnym razie zwraca drugie wyrażenie (0). Zwracana wartość parseInt('')to NaN. NaN ocenia się na false, więc numostatecznie zostaje ustawiony na 0.


6
To nie zadziała, jeśli s = "4s"; (zwraca 4 ... co jest niepoprawne ...)
markzzz

1
Funkcja parseInt w js
parsuje

26
@markzzz Przeczytaj ponownie pytanie. OP pyta: „ Czy można jakoś zwrócić 0 zamiast NaN ”? OP nie chce sprawdzać, czy określony ciąg jest przetwarzalny na int. OP chce dostać 0zamiast NaN. Jest to doskonale rozwiązane przez kod Matta.
trejder

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

2
@ Mateusz, proszę użyć terminów „falsy” lub „prawdy” . ponieważ NaN === fałsz jest fałszem! ale Boolean (NaN) === Boolean (false) jest prawdą. logiczne OR zwraca pierwsze wyrażenie, jeśli można je ocenić jako „prawdomówne”
Pablo Recalde

51

Możesz także użyć isNaN()funkcji:

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

12
Po co dzwonić parseInt(s)dwa razy? Ponadto powinno byćparseInt(s, 10)
Dexygen

2
@GeorgeJempty Podstawa „10” jest domyślna; ten parametr jest opcjonalny. Warto parseInt()jednak dwukrotnie dzwonić .
Jesień Leonard

8
@AutumnLeonard to tylko rodzaj prawdy. Jeśli łańcuch zaczyna się od 0, zakłada się, że liczba jest w formacie ósemkowym, więc parseInt ('077') daje 63. Może to prowadzić do bardzo nieprzyjemnych błędów, więc zawsze powinieneś podać drugi parametr. patrz na przykład stackoverflow.com/questions/8763396/…
chuck258

22

Byłem zaskoczony, gdy nikt nie wspomniał o używaniu Number(). To prawda, że ​​parsuje ułamki dziesiętne, jeśli są podane, więc będzie działał inaczej niż parseInt(), jednak już zakłada podstawową 10 i zmieni „” lub nawet „” na 0.


1
Tak, bardzo przydatny do czytania z localStorage: Number (localStorage.getItem ('appBanner.count')) + 1
Philip Murphy

Chociaż działa to na pytanie, jakie zostało zadane, wciąż zwraca NaN dla nieliczbowych znaków spacji
Kyle Delaney

9

Dla osób, które nie są ograniczone parseInt, możesz użyć bitowego operatora OR (który domyślnie wywołuje ToInt32jego operandy).

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

Uwaga: ToInt32różni się od parseInt. (tj. parseInt('33Ab') === 33)


Ale: '10000000000' | 0 === 1410065408.
trincot,

@trincot tak, każda wartość> = Math.pow(2, 31)przepełni się.
Ahmad Ibrahim,

8

Problem

Inne odpowiedzi nie biorą pod uwagę, że 0jest to fałsz, a zatem następujące będą wynosić 20 zamiast 0:

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

Rozwiązanie

Proponuję funkcję pomocnika, która rozwiązuje większość problemów:

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

Funkcja pomocnika da następujące wyniki:

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
Proszę przesłać podstawkę do parsowania: parseInt(string, radix)rozważ to: Może parseInt("0x10") === 16także parseInt("010")ustąpić 8w niektórych przeglądarkach
andlrc

2
Jeśli już polegasz na lodash dla innych rzeczy, jest przydatna defaultTofunkcja, która robi to: _.defaultTo(NaN, -1)zwraca -1, ale _.defaultTo(0, -1);zwraca 0.
waldyrious,

To doskonały punkt! Możesz polegać tylko na || na koniec, aby podać poprawne ustawienie domyślne, gdy preferowanym ustawieniem domyślnym jest ZERO (oczywiście, właśnie tego chciał PO). Jak już wspomniałeś, z powodu fałszywej natury wejścia „0”, w tym przypadku jest ono traktowane jako nieprawidłowe wejście, a instrukcja zwróci zamiast tego wartość domyślną (być może nie to, czego oczekiwano!)
JonathanDavidArndt

Na pewno powinieneś użyć const zamiast dzwonić parseIntdwa razy
Kyle Delaney

4

Czy praca jest dużo czystsza niż parsowanie Moim zdaniem użyj operatora +

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
Bardzo kompaktowy Szkoda, że ​​nie dostałeś więcej punktów. Głosowałem za tobą. Proszę odwzajemnić się, aby złapać moją -2 zdobytą dzisiaj przez niemego trolla ... (zobacz moją odpowiedź na końcu tej strony). Dziękuję Ci.
Fabien Haddadi,


1

Wykonaj osobne sprawdzenie pustego łańcucha (ponieważ jest to jeden konkretny przypadek) i w tym przypadku ustaw go na zero.

Możesz poprosić „0” na początek, ale musisz dodać przedrostek, aby wskazać, że jest to liczba dziesiętna, a nie ósemkowa


więc uważasz, że lepiej jest dodać 0, jeśli jest puste?
Joper

1
Nie - takiego podejścia użyłem. W takim przypadku osobna kontrola będzie lepsza. Jednak jeśli rozwiązanie Matts działa, jest to jeszcze czystsze.
Schroedingers Cat

1

Dlaczego nie zastąpić funkcji? W takim przypadku zawsze możesz mieć pewność, że zwróci 0w przypadku NaN:

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

Teraz w dowolnym miejscu kodu:

parseInt('') === 0

15
Przesłonięcie takiej funkcji może dezorientować ekspertów programistów JavaScript, którzy mogą uznać to za błąd. Twoja nadpisana funkcja zostanie prawdopodobnie pochowana gdzieś, gdzie raczej nie będzie widoczna. Jest to kreatywne, ale nie jestem pewien, czy osobiście poleciłbym to, biorąc pod uwagę, jak łatwo jest po prostu dodać znak || 0jak w odpowiedzi Matta. Widzę, że nadrzędne obiekty, których nie posiadasz w ostateczności, lub ich brak kosztowałyby znacznie więcej pod względem czasu i złożoności.
jmort253

2
Zgadzam się z @ jmort253 ... To niebezpieczne, ponieważ funkcja jest zbyt inteligentna. Lepiej jest wykonać dokładnie tę samą funkcję, ale o nazwie takiej jak getSafeNumberValue lub coś w tym rodzaju.
Samuel

1

Miałem podobny problem (Firefox V34) z prostymi ciągami, takimi jak:

var myInt = parseInt("b4");

Więc wymyśliłem szybki hack:

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

A potem wszystko głupio skomplikowało zajmowanie się floatami + intami dla nie-prostych rzeczy:

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);

Zwróci 0 za rzeczy takie jak:

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

Czy możesz wyjaśnić to rozwiązanie?
RamenChef

jeśli chcesz przekonwertować dowolną liczbę (np. „123” lub 123) na liczbę całkowitą, jeśli użyjesz parseInt („abc”),
AbdulRahman AlShamiri,

jeśli użyjesz parseInt ('abc'), dostaniesz się do NaN, ale ta funkcja przekształci NaN w 0
AbdulRahman AlShamiri,

Bingo, jako wyraźna alternatywa dla tego ||podejścia. Wiem, że to stare pytanie i odpowiedź, ale ta odpowiedź pozwala uniknąć dwukrotnego wywołania parsowania i poprawnie używa isNaN. Po prostu potrzebuje podstawki, parseInt(x, 10)aby być dokładnym. (Moje preferencje to osobna zmienna wewnętrzna zamiast ponownego użycia x).
goodeye,

1

Stworzyłem 2 prototyp, aby sobie z tym poradzić, jeden dla liczby, a drugi dla ciągu.

// 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);
});

Jeśli nie chcesz korzystać z kontroli bezpieczeństwa, użyj

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

Przykładowe użycie:

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

Wyjaśnienie dla tych, którzy nie uważają tego za trywialne:

Mnożenie przez jeden, metoda nazywana „rzutowaniem niejawnym”, próbuje przekształcić operand nieznanego typu w pierwotny typ „liczba”. W szczególności pusty ciąg stałby się liczbą 0, co czyni go odpowiednim typem dla parseInt () ...

Bardzo dobry przykład podał także powyżej PirateApp, który zasugerował, aby wstawić znak +, zmuszając JavaScript do użycia rzutowania niejawnego Number.


To bezpośrednia odpowiedź na oryginalne pytanie, moja droga.
Fabien Haddadi,

To nie wystarczyparseInt('str'*1)
Rodion Baskakov,

Po co dzwonić parseIntna coś, co już jest numerem? Spowoduje to kolejną konwersję z powrotem na ciąg znaków, aby ponownie przekonwertować ją na liczbę.
trincot,

0

Również w ten sposób, dlaczego nie napisać funkcji i wywołać ją tam, gdzie jest to wymagane. Zakładam, że jest to wpis w polach formularza w celu wykonania obliczeń.

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); 

co jest nie tak robiąc?


Cześć, wat powstrzymuje nas od stosowania powyższej metody. Chciałbym wiedzieć, że się uczę.
Naresh

3
Powinieneś użyć isNaN do testowania NaN.
Matthew

2
Dzięki Matt :) Nie wiem, czy w javascrip jest funkcja o nazwie isNaN ()! Dzięki, że dałeś mi znać...!
Naresh

0

Oto metoda tryParseInt, której używam, która przyjmuje wartość domyślną jako drugi parametr, dzięki czemu może być wszystkim, czego potrzebujesz.

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

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

0

funkcja pomocnicza, która nadal pozwala na korzystanie z podstawki

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

0

Możesz mieć bardzo czysty kod, miałem podobne problemy i rozwiązałem go za pomocą:

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

0

Dla innych osób szukających tego rozwiązania wystarczy użyć: ~~ bez analizy, jest to najczystszy tryb.

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

Jeśli NaN, zwróci 0 zamiast tego.

OBS. To rozwiązanie dotyczy tylko liczb całkowitych

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.