¿Cómo convertir NaN de parseInt en 0 para una cadena vacía?

298

¿Es posible de alguna manera devolver 0 en lugar de NaNanalizar valores en JavaScript?

En caso de que la cadena vacía parseIntregrese NaN.

¿Es posible hacer algo así en JavaScript para verificar NaN?

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

¿O tal vez hay otra función o complemento jQuery que puede hacer algo similar?

Joper
fuente
72
Para su información, NaN != NaN. Se necesitaría isNaN(value).
pimvdb
28
Sí, no hay dos niñeras iguales;)
James P.
3
Llamar a la función parseInt()dos veces (en el NaNcaso no exitoso / normal ) nunca es una buena idea. Además de la ineficiencia, para los incautos, si lo que se pasa tbbes una llamada a la función con efectos secundarios, es terrible. No usaría ninguna solución aquí donde veo parseInt()dos veces.
JonBrave

Respuestas:

756
var s = '';

var num = parseInt(s) || 0;

Cuando no se utiliza con valores booleanos, el ||operador lógico OR ( ) devuelve la primera expresión ( parseInt(s)) si se puede evaluar como verdadero; de lo contrario, devuelve la segunda expresión (0). El valor de retorno de parseInt('')es NaN. NaN se evalúa como falso, por lo que numtermina en 0.

Mateo
fuente
66
Esto no funcionará si s = "4s"; (devuelve 4 ... que es incorrecto ...)
markzzz
1
función parseInt en js analiza cualquier número en cadena
ali youhannaei
26
@markzzz Lea la pregunta nuevamente. OP pregunta: " ¿Es posible de alguna manera devolver 0 en lugar de NaN ". OP no quiere verificar si una cadena particular es analizable a int. OP quiere obtener en 0lugar de NaN. Esto se resuelve con el código de Matt perfectamente.
trejder
2
@markzzzvar nextIphone = parseInt("4S") + 1; // wow it works!
Distracción cero
2
@Matethew, utilice los términos "falso" o "verdadero" . porque NaN === falso es falso! pero booleano (NaN) === Booleano (falso) es verdadero. el OR lógico devuelve la primera expresión si se puede evaluar como "veraz"
Pablo Recalde
52

También puedes usar la isNaN()función:

var s = ''
var num = isNaN(parseInt(s)) ? 0 : parseInt(s)
gprasant
fuente
12
¿Por qué llamar parseInt(s)dos veces? Además debería serparseInt(s, 10)
Dexygen
2
@GeorgeJempty Una raíz de "10" es predeterminada; ese parámetro es opcional. Buen punto en llamar parseInt()dos veces sin embargo.
Otoño Leonard
8
@AutumnLeonard esto solo es cierto. Si su cadena comienza con un 0 se supone que el número está en formato octal, por lo que parseInt ('077') le da 63. Esto puede llevar a que sea muy desagradable encontrar errores, por lo que siempre debe especificar el segundo parámetro. ver por ejemplo stackoverflow.com/questions/8763396/…
chuck258
22

Me sorprendió no ver a nadie mencionar el uso Number(). De acuerdo, analizará decimales si se proporcionan, por lo que actuará de manera diferente que parseInt(), sin embargo, ya asume la base 10 y convertirá "" o incluso "" en 0.

Chris Werner
fuente
1
Sí, muy útil para leer desde localStorage: Number (localStorage.getItem ('appBanner.count')) + 1
Philip Murphy
Si bien eso funciona para la pregunta tal como se hizo, aún devuelve NaN para caracteres que no son espacios en blanco y no son números
Kyle Delaney
9

Para las personas que no están restringidas a parseInt, puede usar el operador OR a nivel de bit (que implícitamente llama ToInt32a sus operandos).

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: ToInt32es diferente de parseInt. (es decir parseInt('33Ab') === 33)

Ahmad Ibrahim
fuente
Pero: '10000000000' | 0 === 1410065408.
trincot
@trincot sí, cualquier valor> = Math.pow(2, 31)se desbordará.
Ahmad Ibrahim
8

El problema

Otras respuestas no tienen en cuenta que 0es falso, y por lo tanto, el siguiente será 20 en lugar de 0:

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

La solución

Propongo una función auxiliar, que resuelve la mayoría de los problemas:

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

La función auxiliar dará los siguientes resultados:

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
sqren
fuente
2
Envíe una raíz a parseInt: parseInt(string, radix)considere esto: parseInt("0x10") === 16también parseInt("010")podría ceder 8en algunos navegadores
andlrc
2
Si ya depende de lodash para otras cosas, hay una defaultTofunción útil que hace exactamente esto: _.defaultTo(NaN, -1)regresa -1, pero _.defaultTo(0, -1);regresa0 .
waldyrious
¡Este es un punto excelente! Solo puede confiar en || al final para proporcionar el valor predeterminado correcto cuando su valor predeterminado preferido es CERO (concedido, esto es lo que quería el OP). Como ha mencionado, debido a la naturaleza falsa de la entrada '0', en este caso se trata como una entrada no válida, y la declaración devolverá el valor predeterminado (¡tal vez no lo que se esperaba!)
JonathanDavidArndt
Seguramente deberías usar una constante en lugar de llamar parseIntdos veces
Kyle Delaney
4

¿El trabajo es mucho más limpio que analizar? En mi opinión, use el operador +

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
PirateApp
fuente
1
Muy compacto Qué pena que no hayas conseguido más puntos. Te he votado. Por favor, corresponda para tratar de atrapar mi -2 adquirido hoy por un troll mudo ... (vea mi respuesta al final de esta página). Gracias.
Fabien Haddadi
2
var value = isNaN(parseInt(tbb)) ? 0 : parseInt(tbb);
Milap Jethwa
fuente
1

Haga una comprobación por separado para una cadena vacía (ya que es un caso específico) y configúrela en cero en este caso.

Puede agregar "0" al inicio, pero luego debe agregar un prefijo para indicar que es un número decimal y no un número octal

Gato Schroedingers
fuente
¿Crees que es mejor agregar 0 si está vacío?
Joper
1
No, ese es un enfoque que he usado. En este caso, un cheque por separado sería mejor. Sin embargo, si la solución Matts funciona, eso es aún más limpio.
Schroedingers Cat
1

¿Por qué no anular la función? En ese caso, siempre puede estar seguro de que vuelve 0en caso de NaN:

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

Ahora, en cualquier parte de su código:

parseInt('') === 0
pimvdb
fuente
15
Anular la función como esta podría confundir a los programadores expertos de JavaScript que podrían ver eso como un error. Es probable que su función anulada esté enterrada en algún lugar donde no sea probable que se vea. Esto es creativo, pero no estoy seguro de recomendarlo personalmente teniendo en cuenta lo fácil que es agregar un || 0como en la respuesta de Matt. Veo objetos primarios que no posee como último recurso o cuando no lo haga costaría mucho más en términos de tiempo y complejidad.
jmort253
2
Estoy de acuerdo con @ jmort253 ... Es peligroso porque la función es demasiado inteligente. Es mejor hacer exactamente la misma función pero con un nombre como getSafeNumberValue o algo así.
Samuel
1

Tuve un problema similar (firefox v34) con cadenas simples como:

var myInt = parseInt("b4");

Entonces se me ocurrió un truco rápido de:

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

Y luego se volvió todo estúpido complicado para lidiar con flotadores + int para cosas no simples:

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

Devolverá 0 para cosas como:

var intVal = slowParseNumber("b"); // yeilds 0
Beto
fuente
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
AbdulRahman AlShamiri
fuente
¿Puedes explicar esta solución?
RamenChef
si desea convertir cualquier número (como '123 'o 123) a entero, si va a usar parseInt (' abc '),
AbdulRahman AlShamiri
si va a usar parseInt ('abc') llegará a NaN pero esta función convertirá el NaN a 0
AbdulRahman AlShamiri
Bingo, como la alternativa explícita al ||enfoque. Sé que esta es una vieja pregunta y respuesta, pero esta respuesta evita llamar a parseInt dos veces y usa isNaN correctamente. Solo necesita que la raíz parseInt(x, 10)sea ​​completa. (Mi preferencia es una variable interna separada en lugar de reutilizar x.)
goodeye
1

Creé un prototipo 2 para manejar esto por mí, uno para un número y otro para una Cadena.

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

Si no desea utilizar el control de seguridad, use

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

Ejemplo de uso:

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
Miguel
fuente
1
// implicit cast
var value = parseInt(tbb*1); // see original question

Explicación, para aquellos que no lo encuentran trivial:

Multiplicando por uno, un método llamado "conversión implícita", intenta convertir el operando de tipo desconocido en el tipo primitivo 'número'. En particular, una cadena vacía se convertiría en el número 0, por lo que es un tipo elegible para parseInt () ...

PirateApp también dio un muy buen ejemplo anteriormente, quien sugirió anteponer el signo +, obligando a JavaScript a usar el número implícito.

Fabien Haddadi
fuente
Es una respuesta directa a la pregunta original, querido.
Fabien Haddadi
Esto no servirá paraparseInt('str'*1)
Rodion Baskakov
¿Por qué llamar parseInta algo que ya es un número? Eso incurrirá en otra conversión de nuevo a cadena solo para convertir eso a número nuevamente.
Trincot
0

También de esta manera, ¿por qué no escribir una función y llamarla donde sea necesario? Supongo que es la entrada en los campos del formulario para realizar cálculos.

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

¿Qué pasa haciendo esto?

Naresh
fuente
Hola, Wat nos impide seguir el método anterior. Me gustaría saber y aprender.
Naresh
3
Debes usar isNaN para probar NaN.
Mateo
2
Gracias Matt :) ¡No sé si hay una función llamada isNaN () en javascrip! Gracias por hacérmelo saber...!
Naresh
0

Aquí hay un método tryParseInt que estoy usando, este toma el valor predeterminado como segundo parámetro, por lo que puede ser cualquier cosa que necesite.

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

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

una función auxiliar que todavía permite usar la raíz

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

Puede tener un código muy limpio, tuve problemas similares y lo resolví usando:

var a="bcd";
~~parseInt(a);
Bishal Gautam
fuente
0

Para otras personas que buscan esta solución, simplemente use: ~~ sin parseInt, es el modo más limpio.

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

Si NaN, devolverá 0 en su lugar.

OBS Esta solución aplica solo para enteros

Marcos Mendes
fuente