---
title: Collections
category: Additional info
---

# Collections

discord.js comes with a utility class known as _`Collection`_.
It extends JavaScript's native _`Map`_ class, so it has all the _`Map`_ features and more!

<Alert title="Warning" type="warning">
	If you're not familiar with _`Map`_, read [MDN's page on
	it](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map) before continuing. You should be
	familiar with _`Array`_ [methods](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) as
	well. We will also use some ES6 features, so read up [here](/additional-info/es6-syntax.md) if you do not know what
	they are.
</Alert>

A _`Map`_ allows for an association between unique keys and their values.
For example, how can you transform every value or filter the entries in a _`Map`_ easily?
This is the point of the _`Collection`_ class!

## Array-like Methods

Many of the methods on _`Collection`_ correspond to their namesake in _`Array`_. One of them is _`find`_:

<CH.Code>

```js
// Assume we have an array of users and a collection of the same users.
array.find((u) => u.discriminator === '1000');
collection.find((u) => u.discriminator === '1000');
```

</CH.Code>

The interface of the callback function is very similar between the two.
For arrays, callbacks usually pass the parameters _`(value, index, array)`_, where _`value`_ is the value iterated to,
_`index`_ is the current index, and _`array`_ is the array. For collections, you would have _`(value, key, collection)`_.
Here, _`value`_ is the same, but _`key`_ is the key of the value, and _`collection`_ is the collection itself instead.

Methods that follow this philosophy of staying close to the _`Array`_ interface are as follows:

- _`find`_
- _`filter`_ - Note that this returns a _`Collection`_ rather than an _`Array`_.
- _`map`_ - Yet this returns an _`Array`_ of values instead of a _`Collection`_!
- _`every`_
- _`some`_
- _`reduce`_
- _`concat`_
- _`sort`_

## Converting to Array

Since _`Collection`_ extends _`Map`_, it is an [iterable](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Iteration_protocols), and can be converted to an _`Array`_ through either _`Array.from()`_ or spread syntax (_`...collection`_).

<CH.Code>

```js
// For values.
Array.from(collection.values());
[...collection.values()];

// For keys.
Array.from(collection.keys());
[...collection.keys()];

// For [key, value] pairs.
Array.from(collection);
[...collection];
```

</CH.Code>

<Alert title="Warning" type="warning">
	Many people convert Collections to Arrays way too much! This can lead to unnecessary and confusing code. Before you
	use _`Array.from()`_ or similar, ask yourself if whatever you are trying to do can't be done with the given _`Map`_ or
	_`Collection`_ methods or with a for-of loop.
</Alert>

## Extra Utilities

Some methods are not from _`Array`_ and are instead entirely new to standard JavaScript.

<CH.Code>

```js
// A random value.
collection.random();

// The first value.
collection.first();

// The first 5 values.
collection.first(5);

// Similar to `first`, but from the end.
collection.last();
collection.last(2);

// Removes anything that meets the condition from the collection.
// Sort of like `filter`, but in-place.
collection.sweep((user) => user.username === 'Bob');
```

</CH.Code>

A more complicated method is _`partition`_, which splits a single Collection into two new Collections based on the provided function.
You can think of it as two \_`filter`\_ methods, but done at the same time:

<CH.Code>

```js
// `bots` is a Collection of users where their `bot` property was true.
// `humans` is a Collection where the property was false instead!
const [bots, humans] = collection.partition((u) => u.bot);

// Both return true.
bots.every((b) => b.bot);
humans.every((h) => !h.bot);
```

</CH.Code>
