Jacob Paris
← Back to all content

Sort an array into groups with reduce

Here I had a user with a list of email addresses to be sorted by domain.

1const emails = [
2 "alice@gmail.com"
3 "bob@gmail.com"
4 "carol@yahoo.ca"
5 "doug@hotmail.com"
6 "ellie@protonmail.com"

While there are many ways to tackle this problem, my preferred is the functional model using Array.prototype.reduce

1const sortedEmails = emails.reduce((groups, email) => {
2 const [account, domain] = email.split('@')
4 if (!groups[domain]) {
5 groups[domain] = []
6 }
8 groups[domain].push(account)
10 return groups
11}, {})

The reduce function iterates each element of the array and passes the return object to the next iteration. The accumulator (named groups here) is set initially as a {} empty object.

For each email, we break it into variables for each the account and the domain. If our current domain isn't already one of our groups, initialize it as an empty array.

Then add the new account name to the group and return groups to pass it into the next iteration.

2 "gmail.com": ["alice", "bob"],
3 "yahoo.ca": ["carol"],
4 "hotmail.com": ["doug"],
5 "protonmail.com": ["ellie"]

It should be noted that this code isn't completely suitable for production environments. While almost every email address has only one @ symbol and this will work for all of those, there are valid email addresses that have multiple. Parsing the entire specification of valid email addresses is outside the scope of this article.

Professional headshot

Hi, I'm Jacob

Hey there! I'm a developer, designer, and digital nomad with a background in lean manufacturing.

About once per month, I send an email with new guides, new blog posts, and sneak peeks of what's coming next.

Everyone who subscribes gets access to the source code for this website and every example project for all my tutorials.

Stay up to date with everything I'm working on by entering your email below.

Unsubscribe at any time.