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?


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.


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)

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.


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)


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

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

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


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


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

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

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

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

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.


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?


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

0

fungsi pembantu yang masih memungkinkan untuk menggunakan radix

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

0

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

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

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.