convertir une chaîne en tableau d'entiers

92

Je veux convertir la chaîne suivante '14 2'en un tableau de deux entiers. Comment puis-je le faire ?

TJ
la source

Réponses:

88

Vous pouvez .split()obtenir un tableau de chaînes , puis effectuer une boucle pour les convertir en nombres, comme ceci:

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

C'est +myArray[i]juste un moyen rapide de faire la conversion des nombres, si vous êtes sûr qu'il s'agit d'entiers, vous pouvez simplement faire:

for(var i=0; i<myArray.length; i++) { myArray[i] = parseInt(myArray[i], 10); } 
Nick Craver
la source
5
plus court: en for(var i=myArray.length; i--;) myArray[i] = myArray[i]|0;utilisant la conversion bit à bit et une boucle plus courte
vsync
1
ou avec ES5:myArray.forEach(function(x,y,z){ z[y]=x|0 })
vsync
3
@vsync - bien sûr ... mais quand un compilateur va le raccourcir encore plus que cela, pourquoi le maintenir pénible? :) La clarté vaut quelques octets supplémentaires, surtout quand elle ne sera pas beaucoup plus longue, voire pas du tout, une fois réduite.
Nick Craver
car pour une fois, je ne minimise pas mon code publié, afin que les autres puissent lire mon code et voir ce qui se passe, et deuxièmement, les opérations au niveau du bit sont beaucoup plus rapides que parseInt.
vsync
5
@vsync - assurez-vous de tester cette affirmation sur tous les navigateurs, je trouve personnellement que le + est plus lisible ... et si vous testez, la plupart des derniers navigateurs, il y a une différence négligeable, de toute façon - en fonction du moteur. En outre, vous pouvez offrir un .min.jset .jssi vous souhaitez exposer votre code ... rappelez-vous que la minification n'est pas pour l'obscurité (ou ne devrait pas l'être, car c'est à peu près inutile pour cela), c'est pour réduire la surcharge HTTP - un chargement de page plus rapide pour vos utilisateurs.
Nick Craver
213

Un rapide pour les navigateurs modernes:

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

// [14, 2]`
xer0x
la source
1
Manière très propre! Devrait être top.
noisette
1
des balles. c'est génial. si frais et si propre.
Todd
2
+1 et ajoutez simplement polyfill pour la prise en charge des navigateurs plus anciens si nécessaire developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
qdev
1
bien, mais comment cela fonctionne-t-il réellement? Vous passez l'objet Number mais je ne sais pas comment il le convertit. Je pensais qu'il fallait passer une fonction à cartographier.
Jarg7
2
oui, c'est vrai. Number () est la fonction transmise à la carte et convertit les valeurs. Consultez la réponse de Todd pour plus de détails.
xer0x
35

SO ... un fil plus ancien, je sais, mais ...

ÉDITER

@RoccoMusolino a eu une belle prise; voici une alternative:

TL; DR:

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

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

Il y a une faille subtile dans les solutions les plus élégantes énumérées ici, en particulier les belles réponses de @amillara et @Marcus.

Le problème se produit lorsqu'un élément du tableau de chaînes n'est pas de type entier, peut-être dans un cas sans validation sur une entrée. Pour un exemple artificiel ...

Le problème:


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

Puisque vous voulez évidemment un tableau PURE int, c'est un problème. Honnêtement , je n'ai pas compris cela avant d'avoir copié le code SO dans mon script ...: /


Le correctif (légèrement moins baller) :


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

Donc, maintenant même lorsque vous avez une chaîne crap int, votre sortie est un tableau d'entiers purs. Les autres sont vraiment sexy dans la plupart des cas, mais je voulais vraiment offrir ma façon de faire la plupart du temps . C'est toujours un one-liner cependant, à mon crédit ...

J'espère que cela fera gagner du temps à quelqu'un!

Todd
la source
1
Totes baller assez pour moi. Merci Todd!
indextwo
5
Attention, cela ne fonctionnera pas si votre chaîne contient un ou plusieurs 0. Zéro se traduit par un booléen = false, donc le filtre booléen ne le conservera pas.
Rocco Musolino
1
vous pouvez remplacer .filter(Boolean)par.filter( (x) => !Number.isNaN(x))
Bob9630
26
var result = "14 2".split(" ").map(function(x){return parseInt(x)});
Amillara
la source
5
Tous les navigateurs ne le prennent pas en charge - cela va casser dans IE, il s'agit d'une fonctionnalité JavaScript 1.6+. En outre, j'ai dit sur une autre réponse, passez toujours une base à parseInt().
Nick Craver
2
J'ai tellement hâte de savoir quand nous pourrons utiliser .mapet similaires dans JS dans n'importe quel navigateur sans bibliothèques supplémentaires.
JAL
5

Une alternative à la réponse de Tushar Gupta serait:

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

// [14, 2]`

Dans le code golf, vous enregistrez 1 caractère. Ici, le "+" est l'opérateur "unaire plus", fonctionne comme parseInt.

Yann Rolland
la source
3

Commencez par diviser la chaîne sur des espaces:

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

Puis convertissez le tableau de chaînes de résultats en nombres entiers:

for (var i in result) {
    result[i] = parseInt(result[i], 10);
}
Marcus Whybrow
la source
2
Vous devriez toujours passer un argument de base à parseInt(), sinon vous pourriez y avoir des octals.
Nick Craver
Si les chaînes ne commencent pas par 0, ou 0xça devrait aller.
Marcus Whybrow
1
S'ils ne le font pas (voyez comment vous avez préfixé cela avec une hypothèse?) ... pourquoi ajouter les 3 caractères nécessaires pour que cela soit correct dans tous ces cas également?
Nick Craver
3

Le point contre parseInt-approche:

Il n'est pas nécessaire d'utiliser des lambdas et / ou de donner un radixparamètre à parseInt, utilisez simplement parseFloatou à la Numberplace.


Les raisons:

  1. Ça marche:

    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. C'est plus court.

  3. C'est un peu plus rapide et tire parti du cache, quand parseInt-approach - ne :

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

Remarque: dans Firefox parseIntfonctionne environ 4 fois plus vite, mais toujours plus lent que les autres. Au total: +e< Number< parseFloat<parseInt

Ankhzet
la source
0

Juste pour le plaisir, j'ai pensé ajouter une forEach(f())solution aussi.

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

// a = [14,2]
ocodo
la source
0
let idsArray = ids.split(',').map((x) => parseInt(x));
Ahmed Said
la source
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire sur la manière et / ou la raison pour laquelle il résout le problème améliorerait la valeur à long terme de la réponse.
Badacadabra
0

Meilleure solution en une ligne:

var answerInt = [];
var answerString = "1 2 3 4";
answerString.split(' ').forEach(function (item) {
   answerInt.push(parseInt(item))
});
Ravi Gaur
la source
Ce n'est pas une chaîne.
delroh
-3

nous la fonction de division :

var splitresult = "14 2".split(" ");
pyvi
la source
3
Cela obtient un tableau de chaînes, pas de nombres.
Nick Craver
Ouups, oui, mal interprété cela. Voir la réponse de Marcus Whybrow ou Nick Craver pour le reste, alors.
pyvi