Konvertieren Sie einen String in ein Array von Ganzzahlen

92

Ich möchte die folgende Zeichenfolge '14 2'in ein Array von zwei Ganzzahlen konvertieren . Wie kann ich es tun ?

TJ
quelle

Antworten:

88

Sie können .split()ein Array von Zeichenfolgen abrufen und diese dann wie folgt in Zahlen konvertieren:

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

Dies +myArray[i]ist nur eine schnelle Möglichkeit, die Zahlenkonvertierung durchzuführen. Wenn Sie sicher sind, dass es sich um Ganzzahlen handelt, können Sie einfach Folgendes tun:

for(var i=0; i<myArray.length; i++) { myArray[i] = parseInt(myArray[i], 10); } 
Nick Craver
quelle
5
kürzer: for(var i=myArray.length; i--;) myArray[i] = myArray[i]|0;mit der bitweisen Konvertierung und kürzeren Schleifen
vsync
1
oder mit ES5:myArray.forEach(function(x,y,z){ z[y]=x|0 })
vsync
3
@vsync - sicher ... aber wenn ein Compiler es noch weiter verkürzen wird, warum sollte es dann schmerzhaft sein, es zu warten? :) Klarheit ist ein paar zusätzliche Bytes wert, besonders wenn es nicht viel länger dauert, wenn es überhaupt einmal verkleinert wird.
Nick Craver
weil ich ausnahmsweise meinen veröffentlichten Code nicht minimiere, damit andere meinen Code lesen und sehen können, was passiert, und zweitens sind bitweise Operationen viel schneller als parseInt.
vsync
5
@vsync - stellen Sie sicher, dass Sie diese Behauptung in allen Browsern testen. Ich persönlich finde, dass das + besser lesbar ist ... und wenn Sie es testen, gibt es bei den meisten der neuesten Browser einen vernachlässigbaren Unterschied - je nach Engine. Sie können auch a anbieten .min.jsund .jswenn Sie Ihren Code verfügbar machen möchten ... denken Sie daran, dass die Minimierung nicht zur Verschleierung dient (oder nicht, da sie dafür ungefähr unbrauchbar ist), sondern zur Reduzierung des HTTP-Overheads - eine schnellere Seitenladung für Ihre Benutzer.
Nick Craver
212

Eine schnelle für moderne Browser:

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

// [14, 2]`
xer0x
quelle
1
Sehr sauberer Weg! Sollte oben sein.
Haselnuss
1
Bälle. Das ist großartig. so frisch und so sauber.
Todd
2
+1 und fügen Sie bei Bedarf einfach Polyfill für die Unterstützung älterer Browser hinzu. Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
qdev
1
schön, aber wie funktioniert das eigentlich? Sie übergeben das Number-Objekt, sind sich aber nicht sicher, wie es konvertiert wird. Ich dachte, Sie müssten eine Funktion übergeben, um sie abzubilden.
Jarg7
2
Ja, das stimmt. Number () ist die an map übergebene Funktion, die die Werte konvertiert. Weitere Informationen finden Sie in der Antwort von Todd.
xer0x
35

SO ... älterer Thread, ich weiß, aber ...

BEARBEITEN

@RoccoMusolino hatte einen schönen Fang; Hier ist eine Alternative:

TL; DR:

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

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

Die hier aufgeführten eleganteren Lösungen weisen einen subtilen Fehler auf, insbesondere die ansonsten schönen Antworten von @amillara und @Marcus.

Das Problem tritt auf, wenn ein Element des Zeichenfolgenarrays nicht ganzzahlig ist, möglicherweise in einem Fall ohne Validierung einer Eingabe. Für ein erfundenes Beispiel ...

Das Problem:


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

Da Sie offensichtlich ein PURE int-Array möchten, ist dies ein Problem. Ehrlich gesagt habe ich das erst verstanden, als ich SO-Code in mein Skript kopiert habe ...: /


Der (etwas weniger Baller) Fix:


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

Selbst wenn Sie jetzt einen Crap-Int-String haben, ist Ihre Ausgabe ein reines Integer-Array. Die anderen sind in den meisten Fällen wirklich sexy, aber ich wollte mein meistens wildes W'actually anbieten . Es ist immer noch ein Einzeiler, zu meiner Ehre ...

Hoffe es spart jemandem Zeit!

Todd
quelle
1
Totes Baller genug für mich. Danke, Todd!
Indextwo
5
Beachten Sie, dass dies nicht funktioniert, wenn Ihre Zeichenfolge eine oder mehrere 0 enthält. Null übersetzt in einen Booleschen Wert = false, sodass der Boolesche Filter ihn nicht beibehält.
Rocco Musolino
1
Sie können ersetzen .filter(Boolean)durch.filter( (x) => !Number.isNaN(x))
Bob9630
26
var result = "14 2".split(" ").map(function(x){return parseInt(x)});
Amillara
quelle
5
Nicht alle Browser unterstützen dies - es wird im IE kaputt gehen, dies ist eine JavaScript 1.6+ Funktion. Auch sagte ich bei einer anderen Antwort, gib immer einen Radix an parseInt().
Nick Craver
2
Ich freue mich sehr darauf, wann wir .mapJS in jedem Browser ohne zusätzliche Bibliotheken verwenden können und ähnliches.
JAL
5

Eine Alternative zur Antwort von Tushar Gupta wäre:

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

// [14, 2]`

Beim Code Golf speichern Sie 1 Zeichen. Hier ist das "+" der Operator "unary plus" und funktioniert wie parseInt.

Yann Rolland
quelle
3

Teilen Sie zuerst die Zeichenfolge auf Leerzeichen:

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

Konvertieren Sie dann das Ergebnisarray von Zeichenfolgen in Ganzzahlen:

for (var i in result) {
    result[i] = parseInt(result[i], 10);
}
Marcus Whybrow
quelle
2
Sie sollten immer ein Radix-Argument an übergeben parseInt(), da Sie sonst möglicherweise Oktale erhalten.
Nick Craver
Wenn die Zeichenfolgen nicht mit beginnen 0oder 0xes in Ordnung sein sollte.
Marcus Whybrow
1
Wenn dies nicht der Fall ist (siehe, wie Sie dem eine Annahme vorangestellt haben?) ... warum die 3 Zeichen hinzufügen, die erforderlich sind, um es auch für all diese Fälle korrekt zu machen?
Nick Craver
3

Der Punkt gegen den parseIntAnsatz:

Es ist nicht erforderlich, Lambdas zu verwenden und / oder radixParameter anzugeben. parseIntVerwenden Sie einfach parseFloatoder Numberstattdessen.


Gründe dafür:

  1. Es funktioniert:

    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. Es ist kürzer.

  3. Es ist ein kleines bisschen schneller und nutzt den Cache, wenn parseInt- Ansatz - nicht :

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

Hinweis: In Firefox parseIntfunktioniert es ungefähr viermal schneller, aber immer noch langsamer als andere. Insgesamt: +e< Number< parseFloat<parseInt

ankhzet
quelle
0

Nur zum Spaß dachte ich, ich würde auch eine forEach(f())Lösung einwerfen .

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

// a = [14,2]
ocodo
quelle
0
let idsArray = ids.split(',').map((x) => parseInt(x));
Ahmed Said
quelle
Während dieser Code die Frage beantworten kann, würde die Bereitstellung eines zusätzlichen Kontexts darüber, wie und / oder warum er das Problem löst, den langfristigen Wert der Antwort verbessern.
Badacadabra
0

Bessere einzeilige Lösung:

var answerInt = [];
var answerString = "1 2 3 4";
answerString.split(' ').forEach(function (item) {
   answerInt.push(parseInt(item))
});
Ravi Gaur
quelle
Das ist keine Schnur.
Delroh
-3

uns die Split-Funktion :

var splitresult = "14 2".split(" ");
pyvi
quelle
3
Dies erhält ein Array von Zeichenfolgen, keine Zahlen.
Nick Craver
Ouups, ja, habe das falsch verstanden. Siehe für den Rest die Antwort von Marcus Whybrow oder Nick Craver.
Pyvi