dizeyi tamsayı dizisine dönüştür


92

Aşağıdaki dizeyi '14 2'iki tamsayı dizisine dönüştürmek istiyorum . Nasıl yapabilirim ?

Yanıtlar:


88

Sen edebilirsiniz .split()dizisini almak için dizeleri , bu gibi sayılara dönüştürmek için içinden sonra döngü:

var myArray = "14 2".split(" ");
for(var i=0; i<myArray.length; i++) { myArray[i] = +myArray[i]; } 
//use myArray, it's an array of numbers

Bu +myArray[i], sayı dönüşümünü yapmanın hızlı bir yoludur, tam sayı olduklarından eminseniz, şunları yapabilirsiniz:

for(var i=0; i<myArray.length; i++) { myArray[i] = parseInt(myArray[i], 10); } 

5
daha kısa: for(var i=myArray.length; i--;) myArray[i] = myArray[i]|0;bitsel dönüştürme ve daha kısa döngü kullanma
vsync

1
veya ES5 ile:myArray.forEach(function(x,y,z){ z[y]=x|0 })
vsync

3
@vsync - elbette ... ama herhangi bir derleyici onu bundan daha da kısaltacaksa, neden bakımını zahmetli hale getirelim? :) Netlik, özellikle küçültüldüğünde çok daha uzun sürmeyecekse, birkaç bayt değerindedir.
Nick Craver

çünkü bir kez olsun, yayınlanan kodumu küçültmüyorum, böylece diğerleri kodumu okuyabilir ve neler olduğunu görebilir ve ikincisi, bitsel işlemler parseInt'ten çok daha hızlıdır.
vsync

5
@vsync - bu iddiayı tüm tarayıcılarda test ettiğinizden emin olun, ben şahsen + 'yı daha okunaklı buluyorum ... ve eğer test ederseniz, en yeni tarayıcıların çoğunda, motora bağlı olarak, her iki şekilde de ihmal edilebilir bir fark vardır. Ayrıca, bir .min.jsve .jseğer kodunuzu ifşa etmek istiyorsanız ... küçültmenin belirsizlik için olmadığını unutmayın (veya olmamalı, çünkü bunun için yararsızdır), HTTP ek yükünü azaltmak için - daha hızlı bir sayfa yüklemesi kullanıcılarınız için.
Nick Craver

213

Modern tarayıcılar için hızlı bir tane:

'14 2'.split(' ').map(Number);

// [14, 2]`

1
Çok temiz bir yol! En iyi olmalı.
fındık

1
topları. bu harika. çok taze ve çok temiz.
Todd

2
+1 ve gerekirse daha eski tarayıcı desteği için polyfill ekleyin. Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
qdev

1
güzel, ama bu gerçekten nasıl çalışıyor? Number nesnesini geçiriyorsunuz, ancak onu nasıl dönüştürdüğünden emin değilim. Haritalamak için bir fonksiyona geçmen gerektiğini düşündüm.
Jarg7

2
evet, bu doğru. Number (), haritaya aktarılan işlevdir ve değerleri dönüştürür. Daha fazla ayrıntı için Todd'un cevabına bakın.
xer0x

35

Yani ... eski iplik, biliyorum, ama ...

DÜZENLE

@RoccoMusolino iyi yakaladı; işte bir alternatif:

TL; DR:

 const intArray = [...("5 6 7 69 foo 0".split(' ').filter(i => /\d/g.test(i)))]

YANLIŞ :"5 6 note this foo".split(" ").map(Number).filter(Boolean); // [5, 6]

Burada listelenen daha zarif çözümlerde ince bir kusur var, özellikle @amillara ve @Marcus'un aksi takdirde güzel cevapları.

Sorun, dizge dizisinin bir öğesi tamsayı benzeri olmadığında, belki de bir girdi üzerinde doğrulama olmayan bir durumda ortaya çıkar. Uydurma bir örnek için ...

Sorun:


var effedIntArray = "5 6 7 69 foo".split(' ').map(Number); // [5, 6, 7, 69, NaN]

Açıkça bir PURE int dizisi istediğiniz için, bu bir problemdir. Dürüst olmak gerekirse , SO kodunu kopyalayıp betiğime yapıştırana kadar bunu yakalayamadım ...: /


(Biraz daha düşük suçlu) düzeltme:


var intArray = "5 6 7 69 foo".split(" ").map(Number).filter(Boolean); // [5, 6, 7, 69]

Böylece, artık int dizgeniz bile olsa, çıktınız saf bir tamsayı dizisidir. Diğerleri çoğu durumda gerçekten seksi, ama ben çoğunlukla kendimi abartılı bir şekilde sunmak istedim . Yine de kredim için tek satırlık bir şey ...

Umarım birine zaman kazandırır!


1
Totes baller benim için yeterli. Teşekkürler Todd!
indextwo

5
Dikkat edin, dizeniz bir veya daha fazla 0 içeriyorsa bu işe yaramayacaktır. Zero, boolean = false değerine çevrilir, böylece boolean filtresi onu tutmaz.
Rocco Musolino

1
.filter(Boolean)ile değiştirebilirsiniz.filter( (x) => !Number.isNaN(x))
Bob9630

26
var result = "14 2".split(" ").map(function(x){return parseInt(x)});

5
Tüm tarayıcılar bunu desteklemez - IE'de kırılır, bu bir JavaScript 1.6+ özelliğidir. Ayrıca, başka bir cevapta, her zaman bir sayıya bir sayı verin dedim parseInt().
Nick Craver

2
.mapEk kitaplıklar olmadan herhangi bir tarayıcıda JS'de ne zaman kullanabileceğimizi ve benzerlik yapabileceğimizi sabırsızlıkla bekliyorum .
JAL

5

Tushar Gupta cevabının bir alternatifi şöyle olacaktır:

'14 2'.split(' ').map(x=>+x);

// [14, 2]`

Kod golfünde 1 karakter kaydedersiniz. Burada "+" "tekli artı" operatörüdür, parseInt gibi çalışır.


3

Önce dizeyi boşluklara ayırın:

var result = '14 2'.split(' ');

Ardından, sonuç dizeleri dizisini tamsayılara dönüştürün:

for (var i in result) {
    result[i] = parseInt(result[i], 10);
}

2
Her zaman için bir radix argümanı parseInt()iletmelisiniz, aksi takdirde orada sekizli alabilirsiniz.
Nick Craver

Dizeler ile başlamazsa 0veya 0xiyi olmalı.
Marcus Whybrow

1
Eğer onlar (bir varsayımıyla bu öneki nasıl?) Yok ... neden çok bu durumlarda tüm düzeltmek yapmak için gereken 3 karakter ekleyin?
Nick Craver

3

parseInt-Yaklaşıma karşı olan nokta :

Lambdas kullanmaya ve / veya radixparametre vermeye gerek yoktur parseInt, sadece parseFloatveya Numberyerine kullanın.


Sebepler:

  1. İşe yarıyor:

    var src = "1,2,5,4,3";
    var ids = src.split(',').map(parseFloat); // [1, 2, 5, 4, 3]
    
    var obj = {1: ..., 3: ..., 4: ..., 7: ...};
    var keys= Object.keys(obj); // ["1", "3", "4", "7"]
    var ids = keys.map(parseFloat); // [1, 3, 4, 7]
    
    var arr = ["1", 5, "7", 11];
    var ints= arr.map(parseFloat); // [1, 5, 7, 11]
    ints[1] === "5" // false
    ints[1] === 5   // true
    ints[2] === "7" // false
    ints[2] === 7   // true
    
  2. Daha kısa.

  3. Biraz daha hızlıdır ve önbellekten yararlanır,parseInt yaklaşma - şunları yapmazsa :

      // execution time measure function
      // keep it simple, yeah?
    > var f = (function (arr, c, n, m) {
          var i,t,m,s=n();
          for(i=0;i++<c;)t=arr.map(m);
          return n()-s
      }).bind(null, "2,4,6,8,0,9,7,5,3,1".split(','), 1000000, Date.now);
    
    > f(Number) // first launch, just warming-up cache
    > 3971 // nice =)
    
    > f(Number)
    > 3964 // still the same
    
    > f(function(e){return+e})
    > 5132 // yup, just little bit slower
    
    > f(function(e){return+e})
    > 5112 // second run... and ok.
    
    > f(parseFloat)
    > 3727 // little bit quicker than .map(Number)
    
    > f(parseFloat)
    > 3737 // all ok
    
    > f(function(e){return parseInt(e,10)})
    > 21852 // awww, how adorable...
    
    > f(function(e){return parseInt(e)})
    > 22928 // maybe, without '10'?.. nope.
    
    > f(function(e){return parseInt(e)})
    > 22769 // second run... and nothing changes.
    
    > f(Number)
    > 3873 // and again
    > f(parseFloat)
    > 3583 // and again
    > f(function(e){return+e})
    > 4967 // and again
    
    > f(function(e){return parseInt(e,10)})
    > 21649 // dammit 'parseInt'! >_<
    

Uyarı: Firefox'ta parseIntyaklaşık 4 kat daha hızlı çalışır, ancak yine de diğerlerinden daha yavaş çalışır. Toplamda: +e< Number< parseFloat<parseInt


0

Sırf eğlenmek için ben de bir forEach(f())çözüm getirmeyi düşündüm .

var a=[];
"14 2".split(" ").forEach(function(e){a.push(parseInt(e,10))});

// a = [14,2]

0
let idsArray = ids.split(',').map((x) => parseInt(x));

Bu kod soruyu yanıtlayabilirken, sorunun nasıl ve / veya neden çözüldüğüne ilişkin ek bağlam sağlamak, yanıtlayanın uzun vadeli değerini artıracaktır.
Badacadabra

0

Daha iyi tek hat çözümü:

var answerInt = [];
var answerString = "1 2 3 4";
answerString.split(' ').forEach(function (item) {
   answerInt.push(parseInt(item))
});

Bu bir dizi değil.
delroh

-3

bize bölünme işlevi :

var splitresult = "14 2".split(" ");

3
Bu, sayıları değil, dizgelerden oluşan bir dizi alır.
Nick Craver

Ouups, evet, yanlış anladım. Öyleyse geri kalanı için Marcus Whybrow veya Nick Craver'ın cevabına bakın.
pyvi
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.