Bagaimana mengubah NaN dari parseInt menjadi 0 untuk string kosong?

298

Apakah mungkin entah bagaimana mengembalikan 0 alih-alih NaNsaat menguraikan nilai dalam JavaScript?

Dalam kasus string kosong parseIntkembali NaN.

Apakah mungkin untuk melakukan hal seperti itu di JavaScript untuk memeriksanya NaN?

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

Atau mungkin ada fungsi lain atau plugin jQuery yang dapat melakukan hal serupa?

Joper
sumber
72
FYI NaN != NaN,. Kamu akan membutuhkan isNaN(value).
pimvdb
28
Ya, tidak ada dua Nanny yang sama;)
James P.
3
Fungsi panggilan parseInt()dua kali (dalam kasus yang berhasil / normal NaN) tidak pernah merupakan ide yang baik. Terlepas dari ketidakefisienan, bagi yang tidak waspada jika apa pun yang dilewatkan tbbadalah panggilan fungsi dengan efek samping itu mengerikan. Saya tidak akan menggunakan solusi apa pun di sini di mana saya melihat parseInt()dua kali.
JonBrave

Jawaban:

756
var s = '';

var num = parseInt(s) || 0;

Ketika tidak digunakan dengan nilai boolean, ||operator logika OR ( ) mengembalikan ekspresi pertama ( parseInt(s)) jika dapat dievaluasi menjadi true, jika tidak maka mengembalikan ekspresi kedua (0). Nilai kembali parseInt('')adalah NaN. NaN dievaluasi menjadi false, sehingga numakhirnya ditetapkan ke 0.

Matius
sumber
6
Ini tidak akan berfungsi jika s = "4s"; (mengembalikan 4 ... yang tidak benar ...)
markzzz
1
parseInt function in js parse angka apa saja dalam string
ali youhannaei
26
@markzzz Baca pertanyaan lagi. OP bertanya: " Apakah mungkin entah bagaimana mengembalikan 0 bukannya NaN ". OP tidak ingin memeriksa, apakah string tertentu dapat diuraikan ke int. OP ingin mendapatkan 0bukan NaN. Ini diselesaikan dengan kode Matt dengan sempurna.
trejder
2
@markzzzvar nextIphone = parseInt("4S") + 1; // wow it works!
Zero Distraction
2
@ Matius, silakan gunakan istilah "falsy" atau "truthy" . karena NaN === false salah! tetapi Boolean (NaN) === Boolean (false) benar. OR logis mengembalikan ekspresi pertama jika dapat dievaluasi menjadi "benar"
Pablo Recalde
52

Anda juga dapat menggunakan isNaN()fungsi ini:

var s = ''
var num = isNaN(parseInt(s)) ? 0 : parseInt(s)
gprasant
sumber
12
Kenapa menelpon parseInt(s)dua kali? Selain itu harusparseInt(s, 10)
Dexygen
2
@ GeorgeJempty Radix "10" adalah default; parameter itu opsional. Poin bagus untuk menelepon parseInt()dua kali.
Autumn Leonard
8
@ AinLeonard ini hanya benar. Jika string Anda dimulai dengan 0 diasumsikan angkanya dalam format oktal sehingga parseInt ('077') memberi Anda 63. Hal ini dapat menyebabkan sangat buruk untuk menemukan bug sehingga Anda harus selalu menentukan parameter kedua. lihat misalnya stackoverflow.com/questions/8763396/...
chuck258
22

Saya terkejut tidak melihat ada yang menyebutkan menggunakan Number(). Mengabulkannya akan menguraikan desimal jika disediakan, jadi akan bertindak berbeda dari parseInt(), namun itu sudah mengasumsikan basis 10 dan akan berubah "" atau bahkan "" menjadi 0.

Chris Werner
sumber
1
Ya, sangat berguna untuk membaca dari localStorage: Number (localStorage.getItem ('appBanner.count')) + 1
Philip Murphy
Sementara itu berfungsi untuk pertanyaan seperti yang ditanyakan, itu masih mengembalikan NaN untuk karakter non-spasi non-angka
Kyle Delaney
9

Untuk orang-orang yang tidak dibatasi parseInt, Anda dapat menggunakan operator ATAU bitwise (yang secara implisit memanggil ToInt32operannya).

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

Catatan: ToInt32berbeda dari parseInt. (yaitu parseInt('33Ab') === 33)

Ahmad Ibrahim
sumber
Tapi: '10000000000' | 0 === 1410065408.
trincot
@trincot ya, nilai apa pun> = Math.pow(2, 31)akan meluap.
Ahmad Ibrahim
8

Masalah

Jawaban lain tidak memperhitungkan yang 0salah, dan dengan demikian yang berikut adalah 20 bukannya 0:

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

Solusinya

Saya mengusulkan fungsi pembantu, yang memecahkan sebagian besar masalah:

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

Fungsi helper akan memberikan hasil berikut:

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
sumber
2
Silakan kirim radix ke parseInt:, parseInt(string, radix)pertimbangkan ini: parseInt("0x10") === 16Juga parseInt("010")dapat menghasilkan 8di beberapa browser
andlrc
2
Jika Anda sudah bergantung pada lodash untuk hal-hal lain, ada defaultTofungsi praktis yang melakukan hal ini: _.defaultTo(NaN, -1)mengembalikan -1, tetapi _.defaultTo(0, -1);mengembalikan 0.
waldyrious
Ini adalah poin yang sangat bagus! Anda hanya bisa mengandalkan || di akhir untuk memberikan default yang benar ketika default pilihan Anda adalah NOL (diberikan, inilah yang diinginkan OP). Seperti yang telah Anda sebutkan, karena input '0' yang salah, itu diperlakukan sebagai input yang tidak valid dalam kasus ini, dan pernyataan itu akan mengembalikan nilai default sebagai gantinya (mungkin bukan apa yang diharapkan!)
JonathanDavidArndt
Tentunya Anda harus menggunakan const daripada menelepon parseIntdua kali
Kyle Delaney
4

Apakah pekerjaannya jauh lebih bersih daripada parseInt menurut saya, Gunakan operator +

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
sumber
1
Sangat kompak. Sayang sekali Anda tidak mendapatkan poin lebih banyak. Saya memilih Anda. Tolong balas untuk mencoba menangkap -2 saya yang diperoleh hari ini oleh troll bisu ... (lihat jawaban saya di akhir halaman ini). Terima kasih.
Fabien Haddadi
2
var value = isNaN(parseInt(tbb)) ? 0 : parseInt(tbb);
Milap Jethwa
sumber
1

Lakukan pemeriksaan terpisah untuk string kosong (karena ini adalah satu kasus khusus) dan setel ke nol dalam kasus ini.

Anda dapat menambahkan "0" ke awal, tetapi kemudian Anda perlu menambahkan awalan untuk menunjukkan bahwa itu adalah desimal dan bukan angka oktal

Schroedingers Cat
sumber
Jadi menurut Anda lebih baik menambahkan 0 jika kosong?
Joper
1
Tidak - itu pendekatan yang saya gunakan. Dalam hal ini, pemeriksaan terpisah akan lebih baik. Namun jika solusi Matts berfungsi, itu bahkan lebih bersih.
Schroedingers Cat
1

Mengapa tidak mengganti fungsi? Dalam hal ini, Anda selalu dapat memastikan itu kembali 0jika NaN:

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

Sekarang, di mana saja dalam kode Anda:

parseInt('') === 0
pimvdb
sumber
15
Mengganti fungsi seperti ini dapat membingungkan para programmer JavaScript yang mungkin melihatnya sebagai bug. Fungsi utama Anda kemungkinan akan dikubur di suatu tempat di mana itu tidak mungkin terlihat. Ini kreatif, tapi saya tidak yakin saya pribadi akan merekomendasikannya mengingat betapa mudahnya menambahkan saja || 0seperti dalam jawaban Matt. Saya melihat objek utama yang tidak Anda miliki sebagai pilihan terakhir atau jika tidak melakukannya akan jauh lebih mahal dalam hal waktu dan kompleksitas.
jmort253
2
Saya setuju dengan @ jmort253 ... Ini berbahaya karena fungsinya terlalu pintar. Lebih baik melakukan fungsi yang persis sama tetapi dengan nama seperti getSafeNumberValue atau sesuatu seperti itu.
Samuel
1

Saya punya masalah yang sama (firefox v34) dengan string sederhana seperti:

var myInt = parseInt("b4");

Jadi saya datang dengan retasan cepat:

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

Dan kemudian menjadi sangat rumit untuk berurusan dengan mengapung + int untuk hal-hal yang tidak sederhana:

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

Ini akan mengembalikan 0 untuk hal-hal seperti:

var intVal = slowParseNumber("b"); // yeilds 0
bob
sumber
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
sumber
Bisakah Anda menjelaskan solusi ini?
RamenChef
jika Anda ingin mengonversi angka apa pun (seperti '123 'atau 123) ke integer, jika Anda akan menggunakan parseInt (' abc '),
AbdulRahman AlShamiri
jika Anda akan menggunakan parseInt ('abc') Anda akan mendapatkan NaN tetapi fungsi ini akan mengubah NaN menjadi 0
AbdulRahman AlShamiri
Bingo, sebagai alternatif eksplisit untuk ||pendekatan. Saya tahu ini adalah pertanyaan dan jawaban lama, tetapi jawaban ini menghindari memanggil parseInt dua kali, dan menggunakan isNaN dengan benar. Itu hanya perlu radix parseInt(x, 10)untuk menyeluruh. (Preferensi saya adalah variabel internal yang terpisah alih-alih digunakan kembali x.)
goodeye
1

Saya membuat 2 prototipe untuk menangani ini untuk saya, satu untuk nomor, dan satu untuk sebuah 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);
});

Jika Anda tidak ingin menggunakan pemeriksaan keamanan, gunakan

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

Contoh penggunaan:

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

Penjelasan, bagi mereka yang tidak menganggapnya sepele:

Mengalikan dengan satu, metode yang disebut "pemain implisit", mencoba untuk mengubah operan tipe yang tidak dikenal menjadi tipe 'nomor' primitif. Secara khusus, string kosong akan menjadi nomor 0, menjadikannya tipe yang memenuhi syarat untuk parseInt () ...

Contoh yang sangat bagus juga diberikan di atas oleh PirateApp, yang menyarankan untuk menambahkan tanda +, memaksa JavaScript untuk menggunakan pemeran tersirat Number.

Fabien Haddadi
sumber
Ini adalah jawaban langsung untuk pertanyaan asli Dear.
Fabien Haddadi
Ini tidak akan berlaku untukparseInt('str'*1)
Rodion Baskakov
Mengapa memanggil parseIntsesuatu yang sudah menjadi nomor? Itu akan menimbulkan konversi lain kembali ke string hanya untuk mengonversinya menjadi angka lagi.
trincot
0

Juga dengan cara ini, mengapa tidak menulis fungsi dan menyebutnya di mana pun diperlukan. Saya berasumsi itu adalah entri ke bidang formulir untuk melakukan perhitungan.

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

apa yang salah melakukan ini?

Naresh
sumber
Hai, apa yang menghentikan kita dari mengikuti metode di atas. Ingin tahu dan belajar.
Naresh
3
Anda harus menggunakan isNaN untuk menguji NaN.
Matius
2
Terima kasih Matt :) Saya tidak tahu bahwa ada fungsi yang disebut isNaN () di javascrip! Terima kasih telah memberi tahu saya ...!
Naresh
0

Berikut adalah metode tryParseInt yang saya gunakan, ini mengambil nilai default sebagai parameter kedua sehingga bisa apa saja yang Anda butuhkan.

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

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

fungsi pembantu yang masih memungkinkan untuk menggunakan radix

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

Anda dapat memiliki kode yang sangat bersih, saya memiliki masalah yang sama dan saya menyelesaikannya dengan menggunakan:

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

Untuk orang lain yang mencari solusi ini, cukup gunakan: ~~ tanpa parseInt, ini adalah mode terbersih.

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

Jika NaN, itu akan mengembalikan 0 sebagai gantinya.

OBS. Solusi ini hanya berlaku untuk bilangan bulat

Marcos Mendes
sumber