konwertuje ciąg na tablicę liczb całkowitych


92

Chcę przekonwertować następujący ciąg '14 2'na tablicę dwóch liczb całkowitych. Jak mogę to zrobić ?

Odpowiedzi:


88

Możesz .split()uzyskać tablicę ciągów , a następnie zapętlić je, aby przekonwertować je na liczby, na przykład:

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

To +myArray[i]tylko szybki sposób na wykonanie konwersji liczb, jeśli masz pewność, że są to liczby całkowite, możesz po prostu zrobić:

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

5
krótszy: for(var i=myArray.length; i--;) myArray[i] = myArray[i]|0;użycie konwersji bitowej i krótszego zapętlenia
vsync,

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

3
@vsync - jasne ... ale jeśli jakikolwiek kompilator skróci to jeszcze bardziej, po co sprawiać, że będzie bolesne? :) Przejrzystość jest warta kilku dodatkowych bajtów, zwłaszcza jeśli w rzeczywistości nie będzie dużo dłużej, jeśli w ogóle zostanie zminimalizowana.
Nick Craver

ponieważ raz nie minimalizuję opublikowanego kodu, aby inni mogli go odczytać i zobaczyć, co się dzieje, a po drugie, operacje bitowe są znacznie szybsze niż parseInt.
vsync,

5
@vsync - upewnij się, że przetestowałeś to oświadczenie we wszystkich przeglądarkach, osobiście uważam, że + jest bardziej czytelny ... a jeśli testujesz, większość najnowszych przeglądarek ma pomijalną różnicę, tak czy inaczej - w zależności od silnika. Możesz także zaoferować, .min.jsa .jsjeśli chcesz ujawnić swój kod ... pamiętaj, że minifikacja nie jest dla niejasności (lub nie powinna być, ponieważ jest do tego bezużyteczna), służy do zmniejszenia narzutu HTTP - szybsze ładowanie strony dla Twoich użytkowników.
Nick Craver

213

Szybki dla nowoczesnych przeglądarek:

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

// [14, 2]`

1
Bardzo czysty sposób! Powinien być top.
orzech laskowy

1
kulki. to cudownie. tak świeży i czysty.
Todd

2
+1 i po prostu dodaj polyfill do obsługi starszych przeglądarek, jeśli jest to wymagane developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ ...
qdev

1
fajnie, ale jak to właściwie działa? Przekazujesz obiekt Number, ale nie jestem pewien, jak go konwertuje. Myślałem, że musisz przekazać funkcję do mapowania.
Jarg7

2
tak, zgadza się. Number () to funkcja przekazana do mapowania, która konwertuje wartości. Sprawdź odpowiedź Todda, aby uzyskać więcej informacji.
xer0x

35

WIĘC ... starszy wątek, wiem, ale ...

EDYTOWAĆ

@RoccoMusolino miał niezły haczyk; oto alternatywa:

TL; DR:

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

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

Istnieje subtelny błąd w bardziej eleganckich rozwiązaniach wymienionych tutaj, w szczególności w pięknych odpowiedziach @amillara i @Marcus.

Problem występuje, gdy element tablicy ciągów nie jest podobny do liczby całkowitej, być może w przypadku bez weryfikacji danych wejściowych. Na wymyślony przykład ...

Problem:


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

Ponieważ oczywiście potrzebujesz tablicy int PURE, to jest problem. Szczerze mówiąc , nie złapałem tego, dopóki nie skopiowałem kodu SO do mojego skryptu ...: /


(Nieco mniej-Baller) fix:


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

Więc teraz, nawet jeśli masz bzdury int string, twoje wyjście jest czystą tablicą liczb całkowitych. Pozostałe są w większości przypadków naprawdę seksowne, ale ja chciałem oferować głównie moje najmodniejsze w 'w ' właściwie . Mimo wszystko jest to nadal jednowierszowe ...

Mam nadzieję, że zaoszczędzi to komuś czasu!


1
Totes mi wystarczy. Dzięki, Todd!
indekstwo

5
Uważaj, to nie zadziała, jeśli twój łańcuch zawiera jedno lub więcej 0. Zero jest tłumaczone na wartość boolean = false, więc filtr boolowski go nie zachowa.
Rocco Musolino

1
można zastąpić .filter(Boolean)z.filter( (x) => !Number.isNaN(x))
Bob9630

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

5
Nie wszystkie przeglądarki to obsługują - w IE zepsuje się, jest to funkcja JavaScript 1.6+. Ponadto, powiedziałem przy innej odpowiedzi, zawsze przekazuj podstawę do parseInt().
Nick Craver

2
Z niecierpliwością czekam, kiedy będziemy mogli używać .mapi podobnych w JS w dowolnej przeglądarce bez dodatkowych bibliotek.
JAL

5

Alternatywą dla odpowiedzi Tushar Gupta byłoby:

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

// [14, 2]`

W Code Golf oszczędzasz 1 znak. Tutaj „+” to „jednoargumentowy plus”, działa jak parseInt.


3

Najpierw podziel ciąg na spacje:

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

Następnie przekonwertuj wynikową tablicę ciągów na liczby całkowite:

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

2
Zawsze powinieneś przekazywać argument radix do parseInt(), w przeciwnym razie możesz dostać tam ósemki.
Nick Craver

Jeśli łańcuchy nie zaczynają się od 0lub 0xpowinno być dobrze.
Marcus Whybrow

1
Jeśli tak nie jest (widzisz, jak poprzedziłeś to założeniem?) ... po co dodać 3 znaki, które są potrzebne, aby było poprawne we wszystkich tych przypadkach?
Nick Craver

3

Punkt przeciw parseIntpodejściu:

Nie ma potrzeby używania lambd i / lub podawania radixparametru parseInt, po prostu użyj parseFloatlub Number.


Powody:

  1. To działa:

    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. Jest krótszy.

  3. Jest to trochę szybsze i wykorzystuje pamięć podręczną, gdy- parseIntApproach - nie :

      // 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'! >_<
    

Uwaga: W przeglądarce Firefox parseIntdziała około 4 razy szybciej, ale nadal wolniej niż inne. W sumie: +e< Number< parseFloat<parseInt


0

Dla zabawy pomyślałem, że też wrzucę forEach(f())rozwiązanie.

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

Chociaż ten kod może odpowiedzieć na pytanie, dostarczenie dodatkowego kontekstu dotyczącego tego, jak i / lub dlaczego rozwiązuje problem, poprawiłoby długoterminową wartość odpowiedzi.
Badacadabra

0

Lepsze rozwiązanie z jedną linią:

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

To nie jest ciąg.
delroh

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.