convertir cadena en una matriz de enteros

92

Quiero convertir la siguiente cadena '14 2'en una matriz de dos enteros. Cómo puedo hacerlo ?

TJ
fuente

Respuestas:

88

Puede .split()obtener una matriz de cadenas , luego recorrerlas para convertirlas en números, así:

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

El +myArray[i]es sólo una forma rápida de hacer la conversión de números, si está seguro de que son números enteros que sólo puede hacer:

for(var i=0; i<myArray.length; i++) { myArray[i] = parseInt(myArray[i], 10); } 
Nick Craver
fuente
5
más corto: for(var i=myArray.length; i--;) myArray[i] = myArray[i]|0;uso de conversión bit a bit y bucle más corto
vsync
1
o con ES5:myArray.forEach(function(x,y,z){ z[y]=x|0 })
vsync
3
@vsync - seguro ... pero cuando cualquier compilador va a acortarlo aún más, ¿por qué hacer que mantenerlo sea doloroso? :) La claridad vale unos pocos bytes extra, especialmente cuando en realidad no será mucho más larga si se reduce una vez.
Nick Craver
porque por una vez, no minimizo mi código publicado, para que otros puedan leer mi código y ver qué está sucediendo, y segundo, las operaciones bit a bit son mucho más rápidas que parseInt.
vsync
5
@vsync: asegúrese de probar esa afirmación en todos los navegadores, personalmente creo que + es más legible ... y si prueba, la mayoría de los navegadores más recientes hay una diferencia insignificante, de cualquier manera, dependiendo del motor. Además, puede ofrecer un .min.jsy .jssi desea exponer su código ... recuerde que la minificación no es para la oscuridad (o no debería serlo, ya que es inútil para eso), es para reducir la sobrecarga de HTTP: una carga de página más rápida para sus usuarios.
Nick Craver
213

Uno rápido para navegadores modernos:

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

// [14, 2]`
xer0x
fuente
1
¡Manera muy limpia! Debería ser superior.
avellana
1
pelotas. Eso es genial. tan fresco y tan limpio.
Todd
2
+1 y simplemente agregue polyfill para compatibilidad con navegadores antiguos si es necesario developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
qdev
1
bueno, pero ¿cómo funciona esto realmente? Está pasando el objeto Number pero no estoy seguro de cómo lo está convirtiendo. Pensé que necesitabas pasar una función para mapear.
Jarg7
2
sí, eso es correcto. Number () es la función que se pasa al mapa y convierte los valores. Consulte la respuesta de Todd para obtener más detalles.
xer0x
35

SO ... hilo más antiguo, lo sé, pero ...

EDITAR

@RoccoMusolino tuvo una buena captura; aquí hay una alternativa:

TL; DR:

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

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

Hay una falla sutil en las soluciones más elegantes que se enumeran aquí, específicamente en las hermosas respuestas de @amillara y @Marcus.

El problema ocurre cuando un elemento de la matriz de cadenas no es como un número entero, quizás en un caso sin validación en una entrada. Para un ejemplo artificial ...

El problema:


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

Dado que obviamente desea una matriz int PURE, eso es un problema. Honestamente , no entendí esto hasta que copié y pegué el código SO en mi script ...: /


La solución (un poco menos baller) :


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

Entonces, ahora incluso cuando tiene una cadena int de mierda, su salida es una matriz entera pura. Los otros son realmente sexys en la mayoría de los casos, pero en realidad quería ofrecer mi mayor divagación . Sin embargo, todavía es una frase de una sola línea, para mi crédito ...

¡Espero que le ahorre tiempo a alguien!

Todd
fuente
1
Totes baller lo suficiente para mí. ¡Gracias, Todd!
indextwo
5
Tenga cuidado, esto no funcionará si su cadena contiene uno o más 0. El cero se traduce a un booleano = falso, por lo que el filtro booleano no lo mantendrá.
Rocco Musolino
1
puede reemplazar .filter(Boolean)con.filter( (x) => !Number.isNaN(x))
Bob9630
26
var result = "14 2".split(" ").map(function(x){return parseInt(x)});
amillara
fuente
5
No todos los navegadores admiten esto; se romperá en IE, esta es una característica de JavaScript 1.6+. Además, dije en otra respuesta, siempre pase una raíz a parseInt().
Nick Craver
2
Espero con ansias cuando podamos usar .mapy similares en JS en cualquier navegador sin bibliotecas adicionales.
JAL
5

Una alternativa a la respuesta de Tushar Gupta sería:

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

// [14, 2]`

En código golf se guarda 1 carácter. Aquí el "+" es el operador "unario más", funciona como parseInt.

Yann Rolland
fuente
3

Primero divida la cadena en espacios:

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

Luego, convierta la matriz resultante de cadenas en números enteros:

for (var i in result) {
    result[i] = parseInt(result[i], 10);
}
Marcus Whybrow
fuente
2
Siempre debe pasar un argumento de base a parseInt(), de lo contrario, puede obtener octals allí.
Nick Craver
Si las cadenas no comienzan con 0, o 0xdebería estar bien.
Marcus Whybrow
1
Si no lo hacen (¿ves cómo prefijas eso con una suposición?) ... ¿por qué agregar los 3 caracteres necesarios para que sea correcto para todos esos casos también?
Nick Craver
3

El punto en contra del parseIntenfoque:

No es necesario usar lambdas y / o dar un radixparámetro a parseInt, solo use parseFloato en su Numberlugar.


Razones:

  1. Esta funcionando:

    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 mas corto.

  3. Es un poquito más rápido y aprovecha la caché, cuando parseInt-enfoque- no :

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

Aviso: en Firefox parseIntfunciona aproximadamente 4 veces más rápido, pero aún más lento que otros. En total: +e< Number< parseFloat<parseInt

ankhzet
fuente
0

Solo por diversión, pensé en lanzar una forEach(f())solución también.

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

// a = [14,2]
ocodo
fuente
0
let idsArray = ids.split(',').map((x) => parseInt(x));
Ahmed dijo
fuente
Si bien este código puede responder a la pregunta, proporcionar un contexto adicional sobre cómo y / o por qué resuelve el problema mejoraría el valor de la respuesta a largo plazo.
Badacadabra
0

Mejor solución de una línea:

var answerInt = [];
var answerString = "1 2 3 4";
answerString.split(' ').forEach(function (item) {
   answerInt.push(parseInt(item))
});
Ravi Gaur
fuente
Eso no es una cuerda.
Delroh
-3

usamos la función de división :

var splitresult = "14 2".split(" ");
Pyvi
fuente
3
Esto obtiene una matriz de cadenas, no números.
Nick Craver
Ouups, sí, malinterprete eso. Vea la respuesta de Marcus Whybrow o Nick Craver para el resto, entonces.
pyvi