Cómo concatenar cadenas en una matriz en JavaScript

En esta guía, aprenda cómo unir todas las cadenas en una matriz en JavaScript con el método join(), concat() y el operador +, con un punto de referencia de rendimiento que tiene en cuenta varios casos.

Los datos toman muchas formas, y las listas son muy comunes. La concatenación de cadenas es una tarea común y hay varias formas de hacerlo.

De la misma manera, la concatenación de cadenas en una matriz se basa en esa tarea, para cada cadena en esa matriz. Sin embargo, hay otro método muy útil que podemos usar: el método join() que automatiza este proceso sin problemas y sin inconvenientes.

En esta guía, veremos cómo agregar todas las cadenas en una matriz y luego evaluaremos el rendimiento de todos los métodos.

Array.prototype.join()

La forma más fácil de agregar todos los elementos de una matriz en uno es el método join() de la clase Array. Une todos los elementos en una cadena con el delimitador opcional dado.

Si omite el delimitador, se establece en una coma (,):

1
2
3
4
5
6
7
8
9
let platonicSolids = ['Tetrahedron', 'Cube', 'Octahedron', 'Dodecahedron', 'Icosahedron'];

let joinedWithDefaultDelimiter = platonicSolids.join();
let joinedWithDelimiter = platonicSolids.join('');
let joinedWithUnderscore = platonicSolids.join('_');
    
console.log(joinedWithDefaultDelimiter);
console.log(joinedWithDelimiter);
console.log(joinedWithUnderscore);

Esto resulta en:

1
2
3
Tetrahedron,Cube,Octahedron,Dodecahedron,Icosahedron
TetrahedronCubeOctahedronDodecahedronIcosahedron
Tetrahedron_Cube_Octahedron_Dodecahedron_Icosahedron

Esta es una excelente forma de crear entradas a partir de objetos para archivos CSV: definamos un objeto simple con un par de campos y únalos() en una cadena con formato CSV:

1
2
3
4
5
const book = {genre:"Popular Science", name:"Our Mathematical Universe", author:"Max Tegmark"};

let csvString = Object.keys(book).map(field => book[field]).join();

console.log(csvString);

De esta manera, podemos convertir fácilmente un objeto de JavaScript en una cadena con formato CSV, con sus valores de campo unidos:

1
Popular Science,Our Mathematical Universe,Max Tegmark

Cadena.concat()

La función concat() es directa: concatena dos cadenas. Dada una matriz de entradas, podemos simplemente recorrerla y concat() cada entrada en una cadena vacía y devolverla:

1
2
3
4
5
6
7
8
let platonicSolids = ['Tetrahedron', 'Cube', 'Octahedron', 'Dodecahedron', 'Icosahedron'];
let result = '';

for (let i = 0; i < platonicSolids.length; i++) {
    result = result.concat(platonicSolids[i]);
}

console.log(result);

{.icon aria-hidden=“true”}

Recuerda que las cadenas son inmutables y que tenemos que asignar el resultado de la operación concat() a una variable de referencia.

Esto resulta en:

1
TetrahedronCubeOctahedronDodecahedronIcosahedron

También puede agregar cualquier delimitador aquí, simplemente concatenándolo en el ciclo con una verificación para el último elemento:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
let platonicSolids = ['Tetrahedron', 'Cube', 'Octahedron', 'Dodecahedron', 'Icosahedron'];
let result = '';

for (let i = 0; i < platonicSolids.length; i++) {
    result = result.concat(platonicSolids[i]);
    if (i < platonicSolids.length - 1) {
        result = result.concat(",");
    }
}

console.log(result);

Esto resulta en:

1
Tetrahedron,Cube,Octahedron,Dodecahedron,Icosahedron

El operador +

Naturalmente, si puede unir cadenas concat(), también puede agregarlas a través del operador +:

1
2
3
4
5
6
7
8
let platonicSolids = ['Tetrahedron', 'Cube', 'Octahedron', 'Dodecahedron', 'Icosahedron'];
let result = '';

for (let i = 0; i < platonicSolids.length; i++) {
    result = result + platonicSolids[i];
}

console.log(result);

O incluso mejor: puede usar el operador abreviado += en su lugar:

1
result += platonicSolids[i];

Esto también resulta en:

1
TetrahedronCubeOctahedronDodecahedronIcosahedron

Punto de referencia de rendimiento {#punto de referencia de rendimiento}

Entonces, ¿qué enfoque es el mejor en términos de rendimiento? El método join() definitivamente es el más fácil de usar y parece el más limpio, pero ¿es el de mayor rendimiento para grandes corpus de elementos?

Vamos a probar estos métodos y compararlos.

En primer lugar, creemos una función que generará cadenas aleatorias para nosotros:

1
2
3
4
5
6
7
8
function generateStrings(num) {
    let array = [];
    for (let i = 0; i < num; i++) {
        array.push((Math.random() + 1).toString(36).substring(2);
        }
        return array;
    }
}

La función genera un número aleatorio, lo convierte en una cadena con una raíz de 36 y recorta el número sobrante al comienzo de la cadena con substring(). Si bien este método tiene limitaciones para la generación de cadenas, funcionará lo suficientemente bien para hasta 50.000 elementos y serán bastante aleatorios hasta ese punto.

{.icon aria-hidden=“true”}

Nota: Tenga en cuenta que este método no es criptográficamente seguro para números aleatorios, y que solo se usa con fines ilustrativos, para sortear la optimización de almacenamiento en caché innata que encontraríamos al iterar muchas instancias de la misma cadena, para asegurarse de que el punto de referencia sea preciso.

Vamos a probarlo:

1
2
let stringArray = generateStrings(5);
console.log(stringArray)

Esto resulta en:

1
[ 'e8e3mbqczk', '2wqjp9hko', 'szazekngkv', 'xsxl2bvh3w', 'd4vadxk9ny' ]

¡Impresionante! Generemos 25.000 cadenas y juntémoslas con nuestros métodos:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
let stringArray = generateStrings(25000);

console.time('Concatenating with Operator');
let join1 = plusOperator(stringArray);
console.timeEnd('Concatenating with Operator');

console.time('Concatenating with concat()');
let join2 = concat(stringArray);
console.timeEnd('Concatenating with concat()');

console.time('Concatenating with join()');
let join3 = stringArray.join('');
console.timeEnd('Concatenating with join()');


function generateStrings(num) {
    let array = [];
    for (let i = 0; i < num; i++) {
        array.push((Math.random() + 1).toString(36).substring(2));
    }
    return array;
}

function plusOperator(array) {
    let result = '';
    for (let i = 0; i < array.length; i++) {
        result += array[i];
    }
    return result;
}

function concat(array) {
    let result = '';
    for (let i = 0; i < array.length; i++) {
        result = result.concat(array[i]);
    }
    return result;
}

Una vez que se generan y se unen, estos son los resultados:

1
2
3
Concatenating with Operator: 3.417ms
Concatenating with concat(): 2.879ms
Concatenating with join(): 8.930ms

Si está tratando con grandes cantidades de datos, el método join() se ve superado por las implementaciones personalizadas, en gran medida debido a la lógica delimitadora innata. Incluso si no desea agregar un delimitador, en realidad agrega un carácter vacío, lo que requiere más tiempo en matrices grandes.

Si tuviéramos que volver a agregar los delimitadores en nuestros métodos personalizados:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
function plusOperator(array) {
    let result = '';
    for (let i = 0; i < array.length; i++) {
        result += array[i];
        if (i < array.length - 1) {
            result += ',';
        }
    }
    return result;
}

function concat(array) {
    let result = '';
    for (let i = 0; i < array.length; i++) {
        result = result.concat(array[i]);
        if (i < array.length - 1) {
            result = result.concat(',');
        }
    }
    return result;
}

Nuestros resultados serían muy diferentes:

1
2
3
Concatenating with Operator: 3.914ms
Concatenating with concat(): 23.988ms
Concatenating with join(): 3.452ms

El operador funciona un poco más lento que el método join(), y el método concat() se vuelve realmente lento en comparación con ambos enfoques.

También vale la pena señalar la declaración oficial de MDN, con respecto a los beneficios de rendimiento de la concatenación cadenas con el método concat() o los operadores es:

Se recomienda encarecidamente que se utilicen los operadores de asignación (+, +=) en lugar del método concat().

Sin embargo, esto no tiene por qué ser válido en absoluto, y puede obtener fácilmente concat() para superar al operador +:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
console.time('Concatenating with Operator');
concatWithOperator();
console.timeEnd('Concatenating with Operator');

console.time('Concatenating with Function');
concatWithFunction();
console.timeEnd('Concatenating with Function');

function concatWithOperator() {
    let result = "";
    for (let i = 0; i < 10000; i++) {
      result += i;
    }
}

function concatWithFunction() {
    let result = "";
    for (let i = 0; i < 10000; i++) {
      result = result.concat(i);
    }
}

Esto resulta en:

1
2
Concatenating with Operator: 1.921ms
Concatenating with Function: 0.855ms

Su navegador, su versión, así como el optimizador que utiliza pueden variar de una máquina a otra, y propiedades como esas realmente afectan el rendimiento.

{.icon aria-hidden=“true”}

Pruebe y verifique su propio código en lugar de seguir los consejos al pie de la letra. No todas las máquinas y entornos son iguales, y lo que funciona bien en uno, puede no funcionar bien en otro.

Conclusión

En esta guía, analizamos en detalle los diferentes enfoques para unir una lista de cadenas en una sola cadena, con y sin delimitadores.

Hemos echado un vistazo al método join() común, y también hemos implementado dos métodos propios para mejorar el rendimiento cuando no se necesitan delimitadores.

Finalmente, los hemos evaluado para comparar su desempeño.