Como transformar NaN de parseInt em 0 para uma seqüência de caracteres vazia?


298

É possível, de alguma forma, retornar 0 em vez de NaNanalisar valores em JavaScript?

No caso de a string vazia parseIntretornar NaN.

É possível fazer algo assim em JavaScript para verificar NaN?

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

Ou talvez haja outra função ou plugin jQuery que possa fazer algo semelhante?


72
FYI NaN != NaN,. Você precisaria isNaN(value).
Pimvdb

28
Sim, não existem duas babás iguais;)
James P.

3
Chamar a função parseInt()duas vezes (no NaNcaso positivo / normal ) nunca é uma boa ideia. Além da ineficiência, para os incautos, se tudo o que é passado tbbé uma chamada de função com efeitos colaterais, é terrível. Eu não usaria nenhuma solução aqui onde eu vejo parseInt()duas vezes.
precisa saber é o seguinte

Respostas:


756
var s = '';

var num = parseInt(s) || 0;

Quando não usado com valores booleanos, o ||operador lógico OR ( ) retorna a primeira expressão ( parseInt(s)) se puder ser avaliada como verdadeira, caso contrário, retorna a segunda expressão (0). O valor de retorno de parseInt('')é NaN. NaN é avaliado como false, portanto, numacaba sendo definido como 0.


6
Isso não funcionará se s = "4s"; (ele retorna 4 ... o que é incorreto ...)
markzzz

1
função parseInt em js analisar todos os números em seqüência
ali youhannaei

26
@markzzz Leia a pergunta novamente. O OP pergunta: " É possível, de alguma forma, retornar 0 em vez de NaN ". O OP não deseja verificar se uma sequência específica é analisável como int. OP quer obter em 0vez de NaN. Isso é resolvido pelo código de Matt perfeitamente.
Trejder

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

2
@ Matthew, por favor, use os termos "falsy" ou "truth" . porque NaN === false é falso! mas Booleano (NaN) === Booleano (falso) é verdadeiro. o OR lógico retorna a primeira expressão se ele pode ser avaliado para "truthy"
Pablo Recalde

52

Você também pode usar a isNaN()função:

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

12
Por que ligar parseInt(s)duas vezes? Além disso, deveria serparseInt(s, 10)
Dexygen

2
@GeorgeJempty Uma raiz de "10" é o padrão; esse parâmetro é opcional. Bom ponto de ligar parseInt()duas vezes embora.
Autumn Leonard

8
@AutumnLeonard, isso é apenas verdade. Se sua string começa com 0, assume que o número está no formato octal, portanto, parseInt ('077') fornece 63. Isso pode levar a erros muito desagradáveis ​​para encontrar erros, portanto, você deve sempre especificar o segundo parâmetro. veja por exemplo stackoverflow.com/questions/8763396/…
chuck258 2/16/16

22

Fiquei surpreso ao não ver ninguém mencionar o uso Number(). Se for concedido, ele analisará as casas decimais, se houver, e atuará de maneira diferente parseInt(), porém, já assume a base 10 e transformará "" ou até "" em 0.


1
Sim, muito útil para ler a partir de localStorage: Number (localStorage.getItem ('appBanner.count'))) + 1
Philip Murphy

Embora isso funcione para a pergunta como foi feita, ele ainda retorna NaN para caracteres que não são espaços em branco e não numerados
Kyle Delaney

9

Para pessoas que não estão restritas parseInt, você pode usar o operador OR bit a bit (que implicitamente chama ToInt32seus 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: ToInt32é diferente de parseInt. (ie parseInt('33Ab') === 33)


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

@ Trincot Sim, qualquer valor> = Math.pow(2, 31)irá exceder .
Ahmad Ibrahim

8

O problema

Outras respostas não levam em consideração o 0falso e, portanto, serão 20 em vez de 0:

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

A solução

Proponho uma função auxiliar, que resolve a maioria dos problemas:

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

A função auxiliar fornecerá os seguintes 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

2
Por favor, envie um radix para parseInt parseInt(string, radix)parseInt("0x10") === 16parseInt("010")8
:,

2
Se você já depende do lodash para outras coisas, há uma defaultTofunção útil que faz exatamente isso: _.defaultTo(NaN, -1)retorna -1, mas _.defaultTo(0, -1);retorna 0.
valdioso

Este é um excelente ponto! Você pode confiar apenas no || no final, para fornecer o padrão correto quando o seu padrão preferido for ZERO (concedido, é isso que o OP queria). Como você mencionou, devido à natureza falsa da entrada '0', ela é tratada como entrada inválida nesse caso, e a instrução retornará o valor padrão (talvez não o que era esperado!)
JonathanDavidArndt

Certamente você deve usar um const em vez de ligar parseIntduas vezes
Kyle Delaney

4

Na minha opinião, use o 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

1
Muito compacto. Que pena que você não conseguiu mais pontos. Eu votei em você. Por favor, retroceda para tentar pegar meu -2 adquirido hoje por um troll mudo ... (veja minha resposta no final desta página). Obrigado.
Fabien Haddadi


1

Faça uma verificação separada para uma sequência vazia (como é um caso específico) e defina-a como zero nesse caso.

Você poderia colocar "0" no início, mas precisará adicionar um prefixo para indicar que é um número decimal e não um número octal


então você acha que é melhor acrescentar 0 se vazio?
Joper

1
Não - essa é uma abordagem que usei. Nesse caso, uma verificação separada será melhor. No entanto, se a solução Matts funcionar, isso é ainda mais limpo.
Schroedingers Cat

1

Por que não substituir a função? Nesse caso, você sempre pode ter certeza de que ele retornará 0no caso de NaN:

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

Agora, em qualquer lugar do seu código:

parseInt('') === 0

15
Substituir uma função como essa pode confundir programadores especialistas em JavaScript que podem ver isso como um bug. É provável que sua função substituída esteja enterrada em algum lugar onde provavelmente não será vista. Isso é criativo, mas não tenho certeza se eu o recomendaria pessoalmente, considerando como é fácil adicionar um || 0como na resposta de Matt. Vejo objetos que você não possui como último recurso ou, caso contrário, custaria significativamente mais em termos de tempo e complexidade.
jmort253

2
Estou de acordo com @ jmort253 ... É perigoso porque a função é muito inteligente. É melhor fazer exatamente a mesma função, mas com um nome como getSafeNumberValue ou algo assim.
Samuel

1

Eu tive um problema semelhante (firefox v34) com strings simples como:

var myInt = parseInt("b4");

Então eu vim com um hack rápido de:

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

E então ficou tudo estúpido e complicado de lidar com floats + ints para coisas não 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);

Ele retornará 0 para coisas como:

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

Você pode explicar essa solução?
RamenChef #

se vc quiser converter qualquer número (like'123' ou 123) para inteiro, se você vai usar parseInt ( 'abc'),
Abdulrahman AlShamiri

se você usar parseInt ('abc'), você chegará ao NaN, mas essa função converterá o NaN para 0
AbdulRahman AlShamiri 13/16

Bingo, como alternativa explícita à ||abordagem. Sei que essa é uma pergunta e resposta antiga, mas ela evita chamar parseInt duas vezes e usa isNaN corretamente. Ele só precisa que o radix parseInt(x, 10)seja completo. (A minha preferência é uma variável interna separada em vez de reutilização x.)
goodeye

1

Eu criei um protótipo 2 para lidar com isso para mim, um para um número e outro para uma 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);
});

Se você não quiser usar a verificação de segurança, use

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

Exemplo 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

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

Explicação, para aqueles que não consideram trivial:

A multiplicação por uma, um método chamado "conversão implícita", tenta transformar o operando de tipo desconhecido no tipo primitivo 'número'. Em particular, uma sequência vazia se tornaria o número 0, tornando-a um tipo elegível para parseInt () ...

Um exemplo muito bom também foi dado acima pelo PirateApp, que sugeriu o prefixo +, forçando o JavaScript a usar a conversão implícita do Number.


É uma resposta direta à pergunta original, meu caro.
Fabien Haddadi

Isso não parseInt('str'*1)
serve

Por que chamar parseIntalgo que já é um número? Isso implicará em outra conversão de volta à string apenas para convertê-la em número novamente.
trincot

0

Além disso, por que não escrever uma função e chamá-la sempre que necessário. Estou assumindo que é a entrada nos campos do formulário 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); 

o que há de errado em fazer isso?


Oi, o wat está nos impedindo de seguir o método acima. Gostaria de saber e aprender.
Naresh

3
Você deve usar o isNaN para testar NaN.
Mateus

2
Obrigado Matt :) Não sei se existe uma função chamada isNaN () em javascrip! Obrigado por me avisar ...!
Naresh

0

Aqui está um método tryParseInt que estou usando, que usa o valor padrão como segundo parâmetro para que possa ser qualquer coisa que você precise.

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

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

0

uma função auxiliar que ainda permite usar o radix

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

0

Você pode ter um código muito limpo, tive problemas semelhantes e resolvi-o usando:

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

0

Para outras pessoas que procuram essa solução, basta usar: ~~ sem análise, é o modo mais limpo.

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

Se NaN, retornará 0.

OBS. Esta solução se aplica apenas a números inteiros

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.