Colecciones

Discord.js viene con una clase de utilidad conocida como Collection. Extiende la clase nativa de JavaScript Map, así que tiene todas las funciones de Map y muchas más.

ADVERTENCIA

Si no estás familiarizado con Map, lee la documentación de MDNopen in new window antes de continuar. Deberías estar familiarizado con los métodos de un Arrayopen in new window de igual forma. También usaremos algunas funciones de ES6, así que lee aquí si no sabes qué es.

Un Map te permite hacer una asociación entre llaves únicas y sus valores. Por ejemplo, ¿Cómo podrías transformar cada valor o filtrar las entradas en un Map fácilmente? ¡Ese es el punto de la clase Collection!

Métodos de matrices (Array)

Muchos de los métodos de Collection corresponden a su homónimo en Array. Uno de ellos es find:

// Asumiendo que tenemos una matriz de usuarios y una colección con los mismos usuarios.
array.find(u => u.discriminator === '1000');
collection.find(u => u.discriminator === '1000');
1
2
3

La interfaz de la función callback es bastante similar entre los dos. Para las matrices, los callbacks usualmente pasan los parámetros (value, index, array), donde value es el valor iterado, index es el índice actual y array es la matriz. Para las colecciones, tendrías (value, key, collection). Aquí, value es el mismo, pero key es la llave del valor, y collection es la colección.

Los métodos que siguen esta filosofía de parecerse a la interfaz Array son los siguientes:

  • find
  • filter - Esto retorna una Collection en vez de un Array.
  • map - Sin embargo, esto devuelve un Array de valores en lugar de una Collection.
  • every
  • some
  • reduce
  • concat
  • sort

Convirtiendo a matriz (Array)

Ya que Collection extiende a Map, es iterableopen in new window, y puede ser convertido a un Array ya sea con Array.from() o esparciéndolo (...collection).

// Por valores
Array.from(collection.values());
[...collection.values()];

// Por llaves
Array.from(collection.keys());
[...collection.keys()];

// Por pares de [llave, valor]
Array.from(collection);
[...collection];
1
2
3
4
5
6
7
8
9
10
11

ADVERTENCIA

¡Mucha gente convierte Collections a Arrays demasiado! Esto puede llevar a código innecesario y confuso. Antes de que uses Array.from() o similar, pregúntate a ti mismo si lo que estás haciendo no puede ser hecho con los métodos dados de Map o Collection, o con un búcle for-of.

Utilidades extra

Algunos métodos no provienen de Array y, en cambio, son completamente nuevos en el JavaScript estándar.

// Un valor aleatorio
collection.random();

// El primer valor
collection.first();

// Los primeros 5 valores
collection.first(5);

// Similar a 'first', pero desde el final
collection.last();
collection.last(2);

// Elimina de la colección todo lo que cumpla con la condición.
collection.sweep(user => user.username === 'Bob');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Un método más complicado es partition, que separa una sola Collection en dos nuevas Collections basadas en la función dada. Puedes pensar en ello como dos filtros, pero hechos al mismo tiempo:

// 'bots' es una Collection de usuarios donde su propiedad  'bot' devuelve true.
// 'humans' es una Collection de usuarios donde su propiedad 'bot' devuelve false.
const [bots, humans] = collection.partition(u => u.bot);

// Ambos devuelven true
bots.every(b => b.bot);
humans.every(h => !h.bot);
1
2
3
4
5
6
7