Come trasformare NaN da parseInt in 0 per una stringa vuota?


298

È possibile in qualche modo restituire 0 anziché NaNquando si analizzano valori in JavaScript?

Nel caso della stringa vuota parseIntritorna NaN.

È possibile fare qualcosa del genere in JavaScript per verificare NaN?

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

O forse c'è un'altra funzione o plugin jQuery che può fare qualcosa di simile?


72
Cordiali saluti, NaN != NaN. Ne avresti bisogno isNaN(value).
pimvdb,

28
Sì, non ci sono due tate uguali;)
James P.

3
Chiamare parseInt()due volte la funzione (in caso di successo / normale NaN) non è mai una buona idea. A parte l'inefficienza, per gli incauti se ciò che viene passato tbbè una chiamata di funzione con effetti collaterali è terribile. Non vorrei usare nessuna soluzione qui dove vedo parseInt()due volte.
JonBrave,

Risposte:


756
var s = '';

var num = parseInt(s) || 0;

Se non utilizzato con valori booleani, l' ||operatore logico OR ( ) restituisce la prima espressione ( parseInt(s)) se può essere valutata su true, altrimenti restituisce la seconda espressione (0). Il valore di ritorno di parseInt('')è NaN. NaN viene valutato come falso, quindi numfinisce per essere impostato su 0.


6
Questo non funzionerà se s = "4s"; (restituisce 4 ... che non è corretto ...)
markzzz

1
funzione parseInt in js analizza qualsiasi numero in stringa
ali youhannaei

26
@markzzz Leggi di nuovo la domanda. OP chiede: " È possibile in qualche modo restituire 0 invece di NaN ". OP non vuole verificare se una particolare stringa è analizzabile in int. OP vuole ottenere 0invece di NaN. Questo è risolto perfettamente dal codice di Matt.
Trejder,

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

2
@Matthew, per favore, usa i termini "falsy" o "verità" . perché NaN === false è false! ma Boolean (NaN) === Boolean (false) è vero. l'OR logico restituisce la prima espressione se può essere valutata come "verità"
Pablo Recalde,

52

Puoi anche usare la isNaN()funzione:

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

12
Perché chiamare parseInt(s)due volte? Inoltre dovrebbe essereparseInt(s, 10)
Dexygen

2
@GeorgeJempty Una radice di "10" è predefinita; quel parametro è facoltativo. Un buon punto per chiamare parseInt()due volte però.
Autunno Leonard

8
@AutumnLeonard questo è solo un po 'vero. Se la tua stringa inizia con uno 0 si presume che il numero sia in formato ottale, quindi parseInt ('077') ti dà 63. Questo può portare a errori molto difficili da trovare, quindi dovresti sempre specificare il secondo parametro. vedi ad esempio stackoverflow.com/questions/8763396/...
chuck258

22

Sono stato sorpreso di non vedere nessuno menzionare l'utilizzo Number(). Concesso che analizzerà i decimali se forniti, quindi agirà in modo diverso da parseInt(), tuttavia presuppone già la base 10 e trasformerà "" o addirittura "" su 0.


1
Sì, molto utile per la lettura da localStorage: Number (localStorage.getItem ('appBanner.count')) + 1
Philip Murphy,

Mentre funziona per la domanda come è stata posta, restituisce ancora NaN per i caratteri non numerici non bianchi
Kyle Delaney,

9

Per le persone a cui non è limitato parseInt, è possibile utilizzare l'operatore OR bit a bit (che chiama implicitamente i ToInt32suoi operandi).

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

Nota: ToInt32è diverso da parseInt. (ie parseInt('33Ab') === 33)


Ma: '10000000000' | 0 === 1410065408.
trincot

@trincot yes, qualsiasi valore> = Math.pow(2, 31)trabocca.
Ahmad Ibrahim il

8

Il problema

Altre risposte non tengono conto del fatto che 0è falso e quindi le seguenti saranno 20 anziché 0:

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

La soluzione

Propongo una funzione di aiuto, che risolve la maggior parte dei problemi:

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

La funzione helper darà i seguenti risultati:

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
Si prega di inviare un radix a parseInt:, parseInt(string, radix)considerare questo: potrebbe parseInt("0x10") === 16anche parseInt("010")cedere 8in alcuni browser
andlrc

2
Se stai già dipendendo da lodash per altre cose, c'è una pratica defaultTofunzione che fa proprio questo: _.defaultTo(NaN, -1)ritorna -1, ma _.defaultTo(0, -1);ritorna 0.
waldyrious

Questo è un punto eccellente! Puoi fare affidamento solo sul || alla fine fornire il valore predefinito corretto quando il valore predefinito preferito è ZERO (garantito, questo è ciò che l'OP voleva). Come hai accennato, a causa della natura errata dell'input "0", in questo caso viene trattato come input non valido e l'istruzione restituirà invece il valore predefinito (forse non quello che ci si aspettava!)
JonathanDavidArndt

Sicuramente dovresti usare una const invece di chiamare parseIntdue volte
Kyle Delaney il

4

A mio avviso, il lavoro è molto più pulito rispetto all'analisi. Utilizza l'operatore +

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
Molto compatto. Che peccato non aver ottenuto più punti. Ti ho votato. Si prega di ricambiare per provare a catturare il mio -2 acquisito oggi da un muto troll ... (vedi la mia risposta alla fine di questa pagina). Grazie.
Fabien Haddadi,


1

Esegui un controllo separato per una stringa vuota (poiché si tratta di un caso specifico) e impostala su zero in questo caso.

È possibile inserire "0" all'inizio, ma è necessario aggiungere un prefisso per indicare che è un numero decimale e non un numero ottale


quindi pensi che sia meglio aggiungere 0 se vuoto?
Joper,

1
No, questo è un approccio che ho usato. In questo caso, sarebbe meglio un controllo separato. Tuttavia, se la soluzione Matts funziona, è ancora più pulito.
Schroedingers Cat,

1

Perché non sovrascrivere la funzione? In tal caso puoi sempre essere sicuro che ritorni 0in caso di NaN:

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

Ora, ovunque nel tuo codice:

parseInt('') === 0

15
Sostituire la funzione in questo modo potrebbe confondere i programmatori JavaScript esperti che potrebbero vederlo come un bug. È probabile che la tua funzione ignorata sia sepolta da qualche parte dove non è probabile che venga vista. Questo è creativo, ma non sono sicuro che lo consiglierei personalmente considerando quanto sia facile aggiungere un || 0come nella risposta di Matt. Vedo gli oggetti prioritari che non possiedi come ultima risorsa o quando non lo fanno costerebbero significativamente più alti in termini di tempo e complessità.
jmort253

2
Sono d'accordo con @ jmort253 ... È pericoloso perché la funzione è troppo intelligente. È meglio fare esattamente la stessa funzione ma con un nome come getSafeNumberValue o qualcosa del genere.
Samuel,

1

Ho avuto un problema simile (firefox v34) con stringhe semplici come:

var myInt = parseInt("b4");

Quindi ho pensato a una rapida modifica di:

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

E poi è diventato tutto stupido complicato da gestire float + ints per cose non semplici:

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

Restituirà 0 per cose come:

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

Puoi spiegare questa soluzione?
RamenChef,

se vuoi convertire qualsiasi numero (come '123 'o 123) in numero intero, se userai parseInt (' abc '),
AbdulRahman AlShamiri

se utilizzerai parseInt ('abc') otterrai NaN ma questa funzione convertirà NaN in 0
AbdulRahman AlShamiri

Bingo, come alternativa esplicita ||all'approccio. So che questa è una vecchia domanda e risposta, ma questa risposta evita di chiamare due volte ParseInt e usa isNaN correttamente. Ha solo bisogno che il radix parseInt(x, 10)sia accurato. (La mia preferenza è una variabile interna separata invece di riutilizzarla x.)
Addio

1

Ho creato un prototipo 2 per gestirlo, uno per un numero e uno per una stringa.

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

Se non si desidera utilizzare il controllo di sicurezza, utilizzare

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

Esempio di utilizzo:

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

Spiegazione, per coloro che non lo trovano banale:

Moltiplicando per uno, un metodo chiamato "cast implicito", tenta di trasformare l'operando di tipo sconosciuto nel tipo 'numero' primitivo. In particolare, una stringa vuota diventerebbe il numero 0, rendendolo un tipo idoneo per parseInt () ...

Un ottimo esempio è stato anche citato in precedenza da PirateApp, che ha suggerito di anteporre il segno +, costringendo JavaScript a utilizzare il cast implicito di Number.


È una risposta diretta alla domanda originale mia cara.
Fabien Haddadi,

Questo non farà perparseInt('str'*1)
Rodion Baskakov

Perché chiamare parseIntqualcosa che è già un numero? Ciò comporterà l'ennesima conversione di nuovo in stringa solo per convertirla nuovamente in numero.
trincot

0

Anche in questo modo, perché non scrivere una funzione e chiamarla dove mai richiesto. Suppongo sia l'ingresso nei campi del modulo per eseguire calcoli.

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

cosa c'è che non va?


Ciao, Wat ci sta impedendo di seguire il metodo sopra. Vorrei sapere n imparare.
Naresh,

3
È necessario utilizzare isNaN per il test NaN.
Matteo

2
Grazie Matt :) Non so che esiste una funzione chiamata isNaN () in javascrip! Grazie per avermi fatto sapere...!
Naresh,

0

Ecco un metodo tryParseInt che sto usando, questo prende il valore predefinito come secondo parametro in modo che possa essere tutto ciò di cui hai bisogno.

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

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

0

una funzione di supporto che consente ancora di utilizzare il radix

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

0

Puoi avere un codice molto pulito, ho avuto problemi simili e l'ho risolto usando:

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

0

Per le altre persone in cerca di questa soluzione, basta usare: ~~ senza analisi, è la modalità più pulita.

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

Se NaN, restituirà invece 0.

OBS. Questa soluzione si applica solo per numeri interi

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.