JavaScript'te bir değişkenin tamsayı olup olmadığı nasıl kontrol edilir?


405

Bir değişkenin JavaScript'te bir tam sayı olup olmadığını nasıl kontrol ederim ve değilse bir uyarı atarım? Bunu denedim, ama çalışmıyor:

<html>
    <head>
        <script type="text/javascript">
            var data = 22;
            alert(NaN(data));
        </script>
    </head>
</html>

2
Burada olasılıklardan biri kullanmaktır parseInt.
Paul

2
jsben.ch/#/htLVw - bunu yapmanın ortak yolları için bir kriter
EscapeNetscape

Buradaki tüm cevaplar gerçekten modası geçmiş. Bugün, Number.isIntegeren az çirkin yol olan yapışmayı öneriyorum .
Benjamin Gruenbaum

@Benjamim sayı tamsayıya dönüştürülebilecek bir dize ise ne olur? ve HTML'de her şey bir dizedir .. yani Number.isInteger ("69") yanlıştır
joedotnot

Yanıtlar:


344

=== operatörünü ( katı eşitlik ) aşağıdaki gibi kullanın ,

if (data === parseInt(data, 10))
    alert("data is integer")
else
    alert("data is not an integer")

95
bu NaN'ı bir tamsayı olarak sayar. Ayrıca benim yöntem karşı kötü performans gösterir. jsperf.com/numbers-and-integers
Blake Regalia

2
örneğinizi yukarıdaki kod üzerinden çalıştırırsanız, bir tamsayı ve diğerini durum olarak bir tamsayı olarak uyarır ... NaN durumunda da NaN türü pareInt'in dönüş değerinin türünden farklıdır () .....
pranag

1
biraz ayrıntı verebilir misiniz? "örnek" yalnızca parseInt kullanmanın typeof anahtar sözcüğü ve modül operatörü kullanmaktan daha kötü performans verdiğini gösterir. ama şimdi ne demek istediğini anlıyorum (NaN! = NaN)
Blake Regalia

4
javascript @connorbode tüm sayılar öylesine, (hayır şamandıra veya çift vardır) aynı türde 2.0 === 2gereksiz ondalık böylece aynı sayıda sadece farklı hali olduğu için parseInt(2.0) === 2.0eşdeğerdir parseInt(2) === 2doğrudur ki
Michael Theriot

1
@BlakeRegalia: Her ne kadar hızlı olsa da, yöntemi bu yanıttan mümkün olan tüm değerleri geçmiyor : stackoverflow.com/a/14794066/843732
c00000fd

506

Bu da, dizeleri potansiyel tamsayılar olarak da yayınlamak mı istiyorsunuz?

Bu yapacaktır:

function isInt(value) {
  return !isNaN(value) && 
         parseInt(Number(value)) == value && 
         !isNaN(parseInt(value, 10));
}

Bitsel işlemlerle

Basit ayrıştırma ve kontrol

function isInt(value) {
  var x = parseFloat(value);
  return !isNaN(value) && (x | 0) === x;
}

Kısa devre ve ayrıştırma işleminden tasarruf:

function isInt(value) {
  if (isNaN(value)) {
    return false;
  }
  var x = parseFloat(value);
  return (x | 0) === x;
}

Ya da belki her ikisi de tek seferde:

function isInt(value) {
  return !isNaN(value) && (function(x) { return (x | 0) === x; })(parseFloat(value))
}

Testler:

isInt(42)        // true
isInt("42")      // true
isInt(4e2)       // true
isInt("4e2")     // true
isInt(" 1 ")     // true
isInt("")        // false
isInt("  ")      // false
isInt(42.1)      // false
isInt("1a")      // false
isInt("4e2a")    // false
isInt(null)      // false
isInt(undefined) // false
isInt(NaN)       // false

İşte keman: http://jsfiddle.net/opfyrqwp/28/

Verim

Testler, kısa devre çözümünün en iyi performansa (ops / sn) sahip olduğunu ortaya koymaktadır.

// Short-circuiting, and saving a parse operation
function isInt(value) {
  var x;
  if (isNaN(value)) {
    return false;
  }
  x = parseFloat(value);
  return (x | 0) === x;
}

İşte bir kıyaslama: http://jsben.ch/#/htLVw

Daha kısa, geniş bir kısa devre şekli istiyorsanız:

function isInt(value) {
  var x;
  return isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
}

Tabii ki, maden işçisinin buna dikkat etmesini öneriyorum.


4
@krisk - Birden fazla çözüm için seçildi. Ayrıca, sağladığınız 4 varyant üzerinde hızlı bir test gerçekleştirin: jsperf.com/tfm-is-integer - ve kısa devre çözümünün en iyi performansa sahip olduğunu belirledi.
tfmontague

1
2099999999999999'da yanlış döndürüyor: - (
jkucharovic

1
@jkucharovic bitwise VEYA operatörü suçludur. Bitsel olmayan sürümü kullanmak true değerini döndürür.
krisk

1
Bu '2'yi yapar. true değerlendirmek
cyberwombat

1
@cyberwombat well bu ondalık sayı 2.0 :-)
Kuba Beránek

120

Söz konusu değişken hakkında hiçbir şey bilmediğinizi varsayarsak, bu yaklaşımı benimsemeniz gerekir:

if(typeof data === 'number') {
    var remainder = (data % 1);
    if(remainder === 0) {
        // yes, it is an integer
    }
    else if(isNaN(remainder)) {
        // no, data is either: NaN, Infinity, or -Infinity
    }
    else {
        // no, it is a float (still a number though)
    }
}
else {
    // no way, it is not even a number
}

Basitçe söylemek gerekirse:

if(typeof data==='number' && (data%1)===0) {
    // data is an integer
}

8
Ne demek istiyorsun? Bu, javascript veri türlerini denetler "1.0", bir dizedir ve bu nedenle bir sayı değildir. Aksi takdirde 1, var my_var=1.0;bu fonksiyon tarafından doğru bir şekilde bir tamsayı olarak tanımlanan bir şekilde ayarlarsanız bir değişkenin değeri olacaktır .
Blake Regalia

4
Yakında, Number.isInteger()işe yarayacak ... o zamana kadar, bu bunu yapmak için iyi bir yoldur
Claudiu

Number.isInteger benim için çalışmıyor. Yanlış bir şey yapmalıyım. Blake'in% 1 çözümü mükemmel çalışıyor.
mcmacerson

104

Number.isInteger() Gidilecek yol gibi görünüyor.

MDN Number.isInteger(), özellikle IE'nin tüm sürümlerini desteklemeyen tarayıcılar için aşağıdaki çoklu dolguyu da sağlamıştır .

MDN sayfasına bağlantı

Number.isInteger = Number.isInteger || function(value) {
    return typeof value === "number" && 
           isFinite(value) && 
           Math.floor(value) === value;
};

2
MDN 9007199254740992 testini kaldırdı
Bernhard Döbler

2
Bu en basit ve "doğru" cevaptır. Yani, JavaScript zaten tamsayı kontrol yöntemi vardır. Yeni bir tane yazmaya gerek yok. isNaN () tamsayı için değil sayısallık testi yapar.
globewalldesk

66

Numaranın kalan olup olmadığını kontrol edebilirsiniz:

var data = 22;

if(data % 1 === 0){
   // yes it's an integer.
}

Dikkat edin, girişiniz de metin olabilirse ve önce olmadığını kontrol etmek istiyorsanız, önce türü kontrol edebilirsiniz:

var data = 22;

if(typeof data === 'number'){
     // yes it is numeric

    if(data % 1 === 0){
       // yes it's an integer.
    }
}

3
@Erwinus: 0 % 1 === 0Konsolda koş . İade trueolarak 0 % 1döner 0.
Hayır

IE'de denediniz mi ;-)
Codebeat

1
@Erwinus: IE9, IE8 ve IE7 uyumluluk modunda 0 % 1döner 0.
Hayır

Gerçekten eski bir IE'de deneyin. ayrıca sıfırın kontrol edilmesi ve tarayıcıya ne yapılacağına güvenmemenin iyi bir programlama yoludur.
Codebeat

62
@Erwinus: Bence gerçeklerini karıştırdın. Eğer bölmek zaman sıfır hata bir bölünme neden olduğu tarafından size bir sayı ile sıfır bölmek değilken sıfır. IE sürümü ile hiçbir ilgisi yok.
Hayır

22

Basit bir normal ifade kullanabilirsiniz:

function isInt(value) {
    var er = /^-?[0-9]+$/;
    return er.test(value);
}

15

Öncelikle, NaN bir "sayı" dır (evet garip olduğunu biliyorum, sadece onunla yuvarlan) ve bir "işlev" değil.

Değişkenin türünün bir sayı olup olmadığını kontrol etmeniz ve tamsayı olup olmadığını kontrol etmek için modül kullanmanız gerekir.

alert(typeof data === 'number' && data%1 == 0);

2
şöyle olmalıdır: alert (tipeof data == 'number' && (data == 0 || data% 1 == 0)); sıfıra bölmekten kaçınmak için.
Codebeat

19
@Erwinus 0% 1 hala 1'e bölünüyor.
Phil

@Phil, (0 == 0 || 0 % 1 == 0)değerlendirir true.
tomekwi

Ah, bu arada 0 % 1 == 0da değerlendirir true! %bölünme değildir!
tomekwi

13

Kullanırken dikkatli olun

sayı% 1

boş dize ('') veya boole (doğru veya yanlış) tamsayı olarak döner. Bunu yapmak istemeyebilirsiniz

false % 1 // true
'' % 1 //true

Number.isInteger (veri)

Number.isInteger(22); //true
Number.isInteger(22.2); //false
Number.isInteger('22'); //false

tarayıcıda yapı işlevi. Eski tarayıcıları desteklemez

Alternatifler:

Math.round(num)=== num

Ancak, Math.round () da boş dize ve boole için başarısız olur


8

Poster gibi bir tamsayı isteyip istemediğini kontrol etmek için:

if (+data===parseInt(data)) {return true} else {return false}

data önündeki + işaretini (dizeyi sayıya dönüştürür) ve === ifadesini kesin olarak belirtir.

İşte örnekler:

data=10
+data===parseInt(data)
true

data="10"
+data===parseInt(data)
true

data="10.2"
+data===parseInt(data)
false

6
Bu benim durumum için en akıllı çözüm gibi görünüyor (nerede bir dize bir tam sayı olup olmadığını umursamıyorum). Ancak: neden sadece gitmiyorsunuz return (+data===parseInt(data))?
Swiss Mister


6

En basit ve en temiz ECMAScript-6 çözümü (işleve bir dize veya null gibi sayısal olmayan bir değer iletilse bile yanlış döndürmek için yeterince sağlam olan) aşağıdaki gibidir:

function isInteger(x) { return (x^0) === x; } 

Aşağıdaki çözüm de, yukarıdaki çözüm kadar zarif olmasa da işe yarayacaktır:

function isInteger(x) { return Math.round(x) === x; }

Not math.ceil () veya Math.floor (), yukarıdaki uygulamada (yerine Math.Round () arasında) kullanmak da olabilir.

Veya alternatif olarak:

function isInteger(x) { return (typeof x === 'number') && (x % 1 === 0); }

Oldukça yaygın bir yanlış çözüm şudur:

function isInteger(x) { return parseInt(x, 10) === x; }

Bu ayrıştırma tabanlı yaklaşım, birçok x değeri için iyi çalışır, ancak x oldukça büyük hale geldiğinde, düzgün çalışmaz. Sorun, parseInt () öğesinin ayrıştırılmadan önce ilk parametresini bir dizeye zorlamasıdır. Bu nedenle, sayı yeterince büyüdüğünde, dize temsili üstel biçimde sunulacaktır (örneğin, 1e + 21). Buna göre, parseInt () daha sonra 1e + 21'i ayrıştırmaya çalışır, ancak e karakterine ulaştığında ayrışmayı durdurur ve bu nedenle 1 değerini döndürür.

> String(1000000000000000000000)
'1e+21'

> parseInt(1000000000000000000000, 10)
1

> parseInt(1000000000000000000000, 10) === 1000000000000000000000
false

6

Neden kimse bahsetmedi Number.isInteger() ?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger

Benim için mükemmel çalışıyor ve sorunu NaNbir numarayla başlıyor.


1
Bunun ES6 olduğunu unutmayın, bu nedenle eski tarayıcılar (IE <= 11 gibi) bunu desteklemez. Yukarıdaki dokümanlar bir poli dolgu sağlar.
bishop

Birisi Number.isInteger()sizden 3,5 yıl önce bahsetti : stackoverflow.com/a/27424770/5208540
Alex Stragies

bir girişten bir değer yakalayacaksak, giriş değeri dize veri tipinde olduğundan Number.isInteger her zaman false değerini döndürür
Shinigamae

6

ES6'da Sayı Nesnesi için yeni yöntemler eklenir.

İçinde argüman bir tamsayı ise Number.isInteger () yöntemi true değerini döndürür.

Örnek kullanım:

Number.isInteger(10);        // returns true
Number.isInteger(10.5);      // returns false

4

ECMA-262 6.0 (ES6) standardı Number.isInteger işlevini içerir.

Eski tarayıcıya destek eklemek için aşağıdakilerden güçlü ve topluluk destekli bir çözüm kullanmanızı şiddetle tavsiye ederim:

https://github.com/paulmillr/es6-shim

hangi saf ES6 JS çoklu dolgular kütüphanesi .

Bu lib es5-shim gerektirir unutmayın, sadece README.md izleyin.


4

Örneğin, dize biçiminde bir tamsayı Number.isInteger(Number(value))olup olmadığını deneyebilir ve bunun değerlendirilmesini isteyebilirsiniz . Denemekten kaçının çünkü bu her zaman doğru değeri döndürmez. Örneğin , uygulamayı kullanırsanız ve kullanırsanız, yine de doğru dönecektir.valuevar value = "23"trueNumber.isInteger(parseInt(value))var value = "23abc"parseInt

Ama kesinlikle tamsayı değerler istiyorsanız, muhtemelen Number.isInteger(value)hile yapmalısınız.


1
Bunun IE tarafından desteklenmediğini unutmayın; burada docu belirtildiği gibi ben özellikle benim kontrol var var undefined ise bu yüzden benim senaryo durduruldu
mikewasmike

4
var x = 1.5;
if(!isNaN(x)){
 console.log('Number');
 if(x % 1 == 0){
   console.log('Integer');
 }
}else {
 console.log('not a number');
}

3
29 cevaptan sonra, cevabınızı öne çıkarmak için biraz daha açıklama beklenir ...
brasofilo

3

Değişkenin bir tamsayıya yuvarlanmış aynı değişkene eşit olup olmadığını kontrol edin:

if(Math.round(data) != data) {
    alert("Variable is not an integer!");
}

Çok kolayca dönen bu işlevin sorunu çözebilirsiniz trueiçin NaNbasitçe değiştirerek, !=karşı !==ve evirmeyen ifblokları. Bu NaN, JavaScript'te kendisine eşit olmayan tek değer olduğu için çalışır . Örneğin, yeni kod şu olmalıdırif (Math.round(x) === x) { /* x IS an integer! */ }
mgthomas99

3

Ayrıca Number.isInteger(). Belki buradaNumber.isSafeInteger() başka bir seçenek belirtilen ES6'yı kullanan .

Polyfill için Number.isSafeInteger(..)ön ES6 tarayıcılarda:

Number.isSafeInteger = Number.isSafeInteger || function(num) {
    return typeof num === "number" && 
           isFinite(num) && 
           Math.floor(num) === num &&
           Math.abs( num ) <= Number.MAX_SAFE_INTEGER;
};

3

Number.isInteger() tarayıcınız destekliyorsa en iyi yoldur, eğer değilse, gitmek için pek çok yol olduğunu düşünüyorum:

function isInt1(value){
  return (value^0) === value
}

veya:

function isInt2(value){
  return (typeof value === 'number') && (value % 1 === 0); 
}

veya:

function isInt3(value){
  return parseInt(value, 10) === value; 
}

veya:

function isInt4(value){
  return Math.round(value) === value; 
}

şimdi sonuçları test edebiliriz:

var value = 1
isInt1(value)   // return true
isInt2(value)   // return true
isInt3(value)   // return true
isInt4(value)   // return true

var value = 1.1
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

var value = 1000000000000000000
isInt1(value)   // return false
isInt2(value)   // return true
isInt3(value)   // return false
isInt4(value)   // return true

var value = undefined
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

var value = '1' //number as string
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

Bu nedenle, tüm bu yöntemler çalışır, ancak sayı çok büyük olduğunda, parseInt ve ^ operatörü iyi çalışmaz.


3

Sadece şunu deneyin:

let number = 5;
if (Number.isInteger(number)) {
    //do something
}

Number.isInteger (), IE tarayıcılarının tüm sürümlerinde desteklenmez.
SKR

2

Bu işlevi kullanabilirsiniz:

function isInteger(value) {
    return (value == parseInt(value));
}

Değer bir tamsayı değeri içeren bir dize olsa bile true değerini döndürür.
Yani sonuçlar şöyle olacak:

alert(isInteger(1)); // true
alert(isInteger(1.2)); // false
alert(isInteger("1")); // true
alert(isInteger("1.2")); // false
alert(isInteger("abc")); // false

2

Benim yaklaşımım:

a >= 1e+21Test sadece bir sayı ve çok büyük bir değer için geçebilir . Bu, bu tartışmada sunulan diğer çözümlerin aksine, tüm vakaları kesin olarak kapsayacaktır.

a === (a|0)Verilen işlevin bağımsız değişkeni, bitsel olarak dönüştürülmüş değerle tam olarak (===) aynıysa, bağımsız değişkenin bir tam sayı olduğu anlamına gelir.

a|0dönecektir 0herhangi değeri için abu bir sayı değil ve eğer abir numara gerçekten de o kadar ondalık noktadan sonra bir şey uzakta şerit olacak 1.0001olacak1

function isInteger(a){
    return a >= 1e+21 ? true : a === (a|0)
}

/// tests ///////////////////////////
[
  1,                        // true
  1000000000000000000000,   // true
  4e2,                      // true
  Infinity,                 // true
  1.0,                      // true
  1.0000000000001,          // false
  0.1,                      // false
  "0",                      // false
  "1",                      // false
  "1.1",                    // false
  NaN,                      // false
  [],                       // false
  {},                       // false
  true,                     // false
  false,                    // false
  null,                     // false
  undefined                 // false
].forEach( a => console.log(typeof a, a, isInteger(a)) )


1
İyi bir fikir! Testlerinizi gösterdiğinizi de sevdim ama maalesef bu "0" String değerini dikkate almıyor.
Jammer

Hey @vsync, Kasten değil. Başlangıçta upvote yaptım ama önceki yorumumdan dolayı geri döndürmeye karar verdim. Yanlışlıkla çift tıklamam gerekiyordu.
Jammer

1

Bunun için regexp kullanabilirsiniz:

function isInteger(n) {
    return (typeof n == 'number' && /^-?\d+$/.test(n+''));
}


1

|Operatörü kullanın :

(5.3 | 0) === 5.3 // => false
(5.0 | 0) === 5.0 // => true

Yani, bir test işlevi şöyle görünebilir:

var isInteger = function (value) {
  if (typeof value !== 'number') {
    return false;
  }

  if ((value | 0) !== value) {
    return false;
  }

  return true;
};

1

Bu, bir senaryo daha ( 121. ) çözecek , sonunda bir nokta

function isInt(value) {
        var ind = value.indexOf(".");
        if (ind > -1) { return false; }

        if (isNaN(value)) {
            return false;
        }

        var x = parseFloat(value);
        return (x | 0) === x;

    }

1

Ayırıcı içermeyen pozitif tamsayı değerleri için:

return ( data !== '' && data === data.replace(/\D/, '') );

Testler 1. boş değilse ve 2. değer, içindeki sayısal olmayan bir karakterin değiştirilmesinin sonucuna eşitse.


1

Tamam eksi var, çünkü örneğimi tarif etmedi, bu yüzden daha fazla örnek :):

Düzenli ifade ve test yöntemi kullanıyorum:

var isInteger = /^[0-9]\d*$/;

isInteger.test(123); //true
isInteger.test('123'); // true
isInteger.test('sdf'); //false
isInteger.test('123sdf'); //false

// If u want to avoid string value:
typeof testVal !== 'string' && isInteger.test(testValue);

Eksi var çünkü test bir fonksiyon değil.
imlokesh

@imlokesh "bir işlev değil" ne demek? "Yazım yöntemi" yazdım.
Vasyl Gutnyk

@imlokesh sorun değil, sadece soruyorum U çünkü ben üretimde kullandım :) ve u bazı hata buldum sanıyordum :)
Vasyl Gutnyk 26:17

1

ayrıca bu şekilde deneyebilirsin

var data = 22;
if (Number.isInteger(data)) {
    console.log("integer");
 }else{
     console.log("not an integer");
 }

veya

if (data === parseInt(data, 10)){
    console.log("integer");
}else{
    console.log("not an integer");
}

Bu, için yanlış sonuç üretecektir data=22.5;. Ayrıca her iki dalda da var console.log("not an integer"):: S
Colin Breame

0

Bir değişken (dize veya sayı) bir tam sayı olup olmadığını kontrol etmek zorunda kaldı ve bu koşulu kullandım:

function isInt(a){
    return !isNaN(a) && parseInt(a) == parseFloat(a);
}

http://jsfiddle.net/e267369d/1/

Diğer cevapların bazıları benzer bir çözüme sahiptir ( parseFloatbirleşimine dayanır isNaN), ancak benimki daha doğrudan ve kendi kendini açıklamalı olmalıdır.


Düzenleme: Benim yöntem virgül ("1,2" gibi) içeren dizeleri için başarısız olduğunu öğrendim ve ben de benim özel durumda ben bir dize geçerli bir tamsayı değilse (herhangi bir kayan nokta başarısız olmalıdır) işlevi başarısız olmasını istediğini fark 1.0 bile). İşte benim fonksiyonum Mk II:

function isInt(a){
    return !isNaN(a) && parseInt(a) == parseFloat(a) && (typeof a != 'string' || (a.indexOf('.') == -1 && a.indexOf(',') == -1));
}

http://jsfiddle.net/e267369d/3/

Tabii ki, tamsayı kayan noktalı sayıları (1.0 öğe) kabul etmek için işleve ihtiyacınız olması durumunda, her zaman nokta koşulunu kaldırabilirsiniz a.indexOf('.') == -1.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.