¿Cómo puedo obtener una matriz de caracteres de una cadena?

9 minutos de lectura

Avatar de usuario de DarkLightA
OscuridadLuzA

¿Cómo se convierte una cadena en una matriz de caracteres en JavaScript?

Estoy pensando en obtener una cadena como "Hello world!" a la matriz
['H','e','l','l','o',' ','w','o','r','l','d','!']

avatar de usuario de meder omuraliev
meder omuraliev

Nota: Esto no es compatible con Unicode. "I💖U".split('') da como resultado la matriz de 4 caracteres ["I", "�", "�", "u"] lo que puede conducir a errores peligrosos. Consulte las respuestas a continuación para conocer alternativas seguras.

Simplemente divídalo por una cadena vacía.

var output = "Hello world!".split('');
console.log(output);

Ver el String.prototype.split() documentos de MDN.

  • Esto no tiene en cuenta los pares sustitutos. "𨭎".split('') da como resultado ["�", "�"].

    – pista hippie

    13 de febrero de 2015 a las 18:15

  • Vea la respuesta de @hakatashi en otra parte de este hilo. Ojalá todos vean esto… NO USE ESTE MÉTODO, NO ES UNICODE SEGURO

    – i336_

    5 de febrero de 2016 a las 4:22


  • Un poco tarde para la fiesta. Pero, ¿por qué alguien querría hacer una matriz de una cadena? Una cadena ya es una matriz o me equivoco? "randomstring".length; //12 "randomstring"[2]; //"n"

    –Luigi van der Pal

    8 de diciembre de 2016 a las 11:19


  • @LuigivanderPal Una cadena no es una matriz, pero es muy similar. Sin embargo, no es similar a una matriz de caracteres. Una cadena es similar a una matriz de números de 16 bits, algunos de los cuales representan caracteres y otros representan la mitad de un par sustituto. Por ejemplo, str.length no le dice el número de caracteres en la cadena, ya que algunos caracteres ocupan más espacio que otros; str.length le dice la cantidad de números de 16 bits.

    – Theodore Norvell

    5 abr 2019 a las 13:00

avatar de usuario de hakatashi
hakatashi

Como sugiere hippietrail, la respuesta de meder puede romper los pares sustitutos y malinterpretar los “caracteres”. Por ejemplo:

// DO NOT USE THIS!
const a="𝟘𝟙𝟚𝟛".split('');
console.log(a);
// Output: ["�","�","�","�","�","�","�","�"]

Sugiero usar una de las siguientes funciones de ES2015 para manejar correctamente estas secuencias de caracteres.

Difundir sintaxis (ya respondida por insertusernamehere)

const a = [...'𝟘𝟙𝟚𝟛'];
console.log(a);

Array.from

const a = Array.from('𝟘𝟙𝟚𝟛');
console.log(a);

RegExp u bandera

const a="𝟘𝟙𝟚𝟛".split(/(?=[\s\S])/u);
console.log(a);

Usar /(?=[\s\S])/u en lugar de /(?=.)/u porque . no coincide con las nuevas líneas. Si todavía está en la era ES5.1 (o si su navegador no maneja esta expresión regular correctamente, como Edge), puede usar la siguiente alternativa (transpilada por Babel). Tenga en cuenta que Babel también intenta manejar sustitutos no coincidentes correctamente. Sin embargo, esto no parece funcionar para sustitutos bajos sin igual.

const a="𝟘𝟙𝟚𝟛".split(/(?=(?:[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))/);
console.log(a);

Método de reducción (ya respondido por Mark Amery)

const s="𝟘𝟙𝟚𝟛";
const a = [];
for (const s2 of s) {
   a.push(s2);
}
console.log(a);

  • Tenga en cuenta que esta solución divide algunos emoji como 🏳️‍🌈, y divide la combinación de signos diacríticos de los caracteres. Si desea dividir en grupos de grafemas en lugar de caracteres, consulte stackoverflow.com/a/45238376.

    – usuario202729

    30 de agosto de 2018 a las 6:21


  • Tenga en cuenta que si bien no separar los pares sustitutos es excelente, no es una solución de propósito general para mantener “caracteres” (o más exactamente, grafemas) juntos. Un grafema puede estar formado por múltiples puntos de código; por ejemplo, el nombre del idioma Devanagari es “देवनागरी”, que un hablante nativo lee como cinco grafemas, pero requiere ocho puntos de código para producir…

    –TJ Crowder

    17 de septiembre de 2018 a las 12:08

  • La documentación oficial de Mozilla hace referencia a esta respuesta en desarrollador.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – Céfiro

    5 de junio de 2021 a las 22:48

insertusernameaquí el avatar de usuario
insertar nombre de usuario aquí

El spread Sintaxis

Puedes usar el sintaxis extendidaun inicializador de matriz introducido en Estándar ECMAScript 2015 (ES6):

var arr = [...str];

Ejemplos

function a() {
    return arguments;
}

var str="Hello World";

var arr1 = [...str],
    arr2 = [...'Hello World'],
    arr3 = new Array(...str),
    arr4 = a(...str);

console.log(arr1, arr2, arr3, arr4);

Los tres primeros dan como resultado:

["H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d"]

El último resulta

{0: "H", 1: "e", 2: "l", 3: "l", 4: "o", 5: " ", 6: "W", 7: "o", 8: "r", 9: "l", 10: "d"}

Compatibilidad con navegador

Comprobar el Tabla de compatibilidad de ECMAScript ES6.


Otras lecturas

spread también se menciona como “splat” (por ejemplo, en PHP o Rubí o como “scatter” (por ejemplo, en Pitón).


Manifestación

Probar antes de comprar

  • Si usa el operador de propagación en combinación con un compilador para ES5, esto no funcionará en IE. Toma eso en consideración. Me tomó horas descubrir cuál era el problema.

    -Stef van den Berg

    21 de junio de 2017 a las 12:06

Avatar de usuario de Mark Amery
marca amery

Hay (al menos) tres cosas diferentes que podría concebir como un “personaje” y, en consecuencia, tres categorías diferentes de enfoque que podría querer usar.

División en unidades de código UTF-16

Las cadenas de JavaScript se inventaron originalmente como secuencias de unidades de código UTF-16, en un momento de la historia en el que había una relación uno a uno entre las unidades de código UTF-16 y los puntos de código Unicode. El .length propiedad de una cadena mide su longitud en unidades de código UTF-16, y cuando lo hace someString[i] obtienes el iª unidad de código UTF-16 de someString.

En consecuencia, puede obtener una matriz de unidades de código UTF-16 de una cadena mediante el uso de un ciclo for de estilo C con una variable de índice…

const yourString = 'Hello, World!';
const charArray = [];
for (let i=0; i<yourString.length; i++) {
    charArray.push(yourString[i]);
}
console.log(charArray);

También hay varias formas cortas de lograr lo mismo, como usar .split() con la cadena vacía como separador:

const charArray = 'Hello, World!'.split('');
console.log(charArray);

Sin embargo, si su cadena contiene puntos de código que se componen de varias unidades de código UTF-16, esto los dividirá en unidades de código individuales, lo que puede no ser lo que desea. Por ejemplo, la cadena '𝟘𝟙𝟚𝟛' se compone de cuatro puntos de código Unicode (puntos de código 0x1D7D8 a 0x1D7DB) que, en UTF-16, se componen cada uno de dos unidades de código UTF-16. Si dividimos esa cadena usando los métodos anteriores, obtendremos una matriz de ocho unidades de código:

const yourString = '𝟘𝟙𝟚𝟛';
console.log('First code unit:', yourString[0]);
const charArray = yourString.split('');
console.log('charArray:', charArray);

División en puntos de código Unicode

Entonces, ¡tal vez queramos dividir nuestra cadena en puntos de código Unicode! Eso ha sido posible desde que ECMAScript 2015 agregó el concepto de un iterable al idioma Las cadenas ahora son iterables, y cuando itera sobre ellas (por ejemplo, con un for...of bucle), obtiene puntos de código Unicode, no unidades de código UTF-16:

const yourString = '𝟘𝟙𝟚𝟛';
const charArray = [];
for (const char of yourString) {
  charArray.push(char);
}
console.log(charArray);

Podemos acortar esto usando Array.fromque itera sobre el iterable que se pasa implícitamente:

const yourString = '𝟘𝟙𝟚𝟛';
const charArray = Array.from(yourString);
console.log(charArray);

Sin embargo, los puntos de código Unicode no son lo más grande posible que podría considerarse un “carácter” cualquiera. Algunos ejemplos de cosas que razonablemente podrían considerarse un solo “carácter” pero que se componen de múltiples puntos de código incluyen:

  • Caracteres acentuados, si el acento se aplica con un punto de código de combinación
  • Banderas
  • algunos emojis

Podemos ver a continuación que si intentamos convertir una cadena con tales caracteres en una matriz a través del mecanismo de iteración anterior, los caracteres terminan divididos en la matriz resultante. (En caso de que alguno de los caracteres no aparezca en su sistema, yourString abajo consta de un capitel A con acento agudo, seguida de la bandera del Reino Unido, seguida de una mujer negra.)

const yourString = 'Á🇬🇧👩🏿';
const charArray = Array.from(yourString);
console.log(charArray);

Si queremos mantener cada uno de estos como un solo elemento en nuestra matriz final, entonces necesitamos una matriz de grafemasno puntos de código.

División en grafemas

JavaScript no tiene soporte incorporado para esto, al menos no todavía. Entonces, necesitamos una biblioteca que comprenda e implemente las reglas de Unicode para qué combinación de puntos de código constituyen un grafema. Afortunadamente, existe uno: orling’s divisor de grafema. Querrá instalarlo con npm o, si no está usando npm, descargue el archivo index.js y sírvalo con un <script> etiqueta. Para esta demostración, la cargaré desde jsDelivr.

grapheme-splitter nos da una GraphemeSplitter clase con tres métodos: splitGraphemes, iterateGraphemesy countGraphemes. Naturalmente, queremos splitGraphemes:

const splitter = new GraphemeSplitter();
const yourString = 'Á🇬🇧👩🏿';
const charArray = splitter.splitGraphemes(yourString);
console.log(charArray);
<script src="https://cdn.jsdelivr.net/npm/grapheme-splitter@1.0.4/index.js"></script>

Y ahí estamos: una matriz de tres grafemas, que es probablemente que querías.

Avatar de usuario de Rajesh
Rajesh

También puedes usar Array.from.

var m = "Hello world!";
console.log(Array.from(m))

Este método se ha introducido en ES6.

Referencia

Array.from

Avatar de usuario de Peter Mortensen
Pedro Mortensen

Puedes usar el Objeto.asignar función para obtener la salida deseada:

var output = Object.assign([], "Hello, world!");
console.log(output);
    // [ 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!' ]

No es necesariamente correcto o incorrecto, solo otra opción.

Object.assign se describe bien en el sitio de MDN.

avatar de usuario de hash_name
hash_name

ya lo es:

var mystring = 'foobar';
console.log(mystring[0]); // Outputs 'f'
console.log(mystring[3]); // Outputs 'b'

O para una versión más antigua compatible con el navegador, use:

var mystring = 'foobar';
console.log(mystring.charAt(3)); // Outputs 'b'

  • -1: no lo es. Intentalo: alert("Hello world!" == ['H','e','l','l','o',' ','w','o','r','l','d'])

    – R. Martinho Fernández

    28 de diciembre de 2010 a las 16:48


  • Lo siento. Supongo que lo que quise decir es: “puede acceder a caracteres individuales por referencia de índice como este sin crear una matriz de caracteres”.

    – dansimau

    28 de diciembre de 2010 a las 16:50


  • No se puede confiar en varios navegadores. Es una característica de la quinta edición de ECMAScript.

    – bobince

    28 de diciembre de 2010 a las 17:25

  • La versión multinavegador es mystring.charAt(index).

    – psmay

    28 de diciembre de 2010 a las 18:04

  • +1 para charAt()–aunque preferiría usar la variante tipo matriz. Maldito IE.

    – Zenexer

    4 de julio de 2014 a las 2:57


¿Ha sido útil esta solución?