Set

Overview

The @supercharge/set package provides a Set class with helpful methods like .isEmpty(), .find(callback), .map(callback), .filter(callback), and many more.

You already know methods like .map() from arrays and having them available on sets improves your development experience. It’s also convenient to avoid all the for..of loops in your code.

Installation

The @supercharge/set package lives independently from the Supercharge framework. Using it in your application requires you to install it as a project dependency:

npm i @supercharge/set

You can use this package with every project even if it’s not build on Supercharge. Enjoy!

Working With Sets

Import the @supercharge/set package and use it the same way you would use JavaScript’s Set class.

Please notice, the @supercharge/set package is not a drop-in replacement for the native Set class shipped by JavaScript.

JavaScript aligned the Set and Map classes. Aligning sets and maps felt wrong for me. In my opinion, sets are more in line with arrays, not with maps. That’s why this package exists.

It’s the Set class JavaScript should have shipped.

const Set = require('@supercharge/set')

const users = Set.from([])

users.isEmpty()
// true

users
  .add({ id: 1, name: 'Marcus' })
  .add({ id: 2, name: 'Norman' })
  .add({ id: 3, name: 'Christian' })

users.isNotEmpty()
// true

const usernamesArray = users
  .map(user => {
    return user.name
  })
  .toArray()

// [ 'Marcus', 'Norman', 'Christian' ]

const marcus = users.find(user => {
  return user.name === 'Marcus'
})

// { id: 1, name: 'Marcus' }

Available Methods

Here’s a list of available methods on a set instance:

Set.from

  • added in version 2.1

The static Set.from method creates a new set instance for a given iterable, like Array.from:

const numbers = Set.from([1, 2, 1, 2])

numbers.toArray()
// [1, 2]

Set.of

  • deprecated since version 2.1.0. Please use Set.from instead
  • added in version 1.0

The static of method creates a new set instance of the given values. It’s basically a shortcut for new Set(entries):

const set = Set.of(['Marcus', 'Supercharge'])

set.has('Marcus')
// true

add

  • updated in 2.2.0 supporting multiple values (set.add(1, 2, 3))
  • added in version 1.0

The add method adds an item to the end of a set if it doesn’t already exists in the set:

const users = new Set()

users
  .add('Marcus')
  .add('Supercharge')
  .add('Marcus')

users.toArray()
// ['Marcus', 'Supercharge']

Since version 2.2.0 you can add multiple values within a single call:

const users = new Set()

users.add('Marcus', 'Supercharge', 'Marcus')

users.toArray()
// ['Marcus', 'Supercharge']

all

  • added in version 2.2

The all method determines whether all of the values in the set match the given predicate function:

const users = Set.from([
  { id: 1, subscribed: false, name: 'Marcus' },
  { id: 2, subscribed: true, name: 'Supercharge' }
])

users.all(user => {
  return user.subscribed === true
})
// false

users.all(user => {
  return user.id > 0
})
// true

any

  • added in version 2.2

The any method determines whether at least one of the values in the set matches the given predicate function:

const users = Set.from([
  { id: 1, subscribed: false, name: 'Marcus' },
  { id: 2, subscribed: true, name: 'Supercharge' }
])

users.any(user => {
  return user.subscribed === true
})
// true

users.any(user => {
  return user.id === 0
})
// false

at

  • added in version 1.7

The at method returns the item at a given index or undefined if the index exceeds the set’s size.

const users = Set.from(['Marcus', 'Supercharge', 'Norman', 'Christian])

users.at(2)
// 'Norman'

users.at(22)
// undefined

clear

  • added in version 1.0

The clear method removes all entries from the set:

const users = Set.from(['Marcus', 'Supercharge', 'Marcus'])

users.size()
// 2

users.clear()

users.size()
// 0

concat

  • added in version 1.4

The concat method adds an array or individual values to the set.

Set.from([1, 2]).concat([3, 4])
// Set [1, 2, 3, 4]

Set.from([1, 2]).concat(5, 6)
// Set [1, 2, 5, 6]

count

  • added in version 1.4

The count method returns the number of items matching the given predicate function.

const set = Set.from([1, 2, 3, 4, 5])

set.count(value => {
  return value > 2
})
// 3

The count method returns the size of the set when not providing a predicate function.

delete

  • added in version 1.0

The delete method removes the entry identified by the given value:

const users = Set.from(['Marcus', 'Supercharge'])

const removed = users.delete('Marcus')
// true

users.has('Marcus')
// false

Calling set.delete(value) returns true if the given value is present in the set and has been removed. Returns false if the value isn’t present in the set.

filter

  • added in version 1.0

The filter method returns a set containing only items matching the given predicate.

The predicate function will be called once for each entry in the set in insertion order.

const users = Set.from([1, 2, 3])

const names = users.filter((value, set) => {
  return value > 1
})

// Set [2, 3]

find

  • added in version 1.0

The find method returns the first item in the set matching the given predicate.

const users = Set.from([
  { id: 1, name: 'Marcus' },
  { id: 2, name: 'Supercharge' }
])

const names = users.find((value, set) => {
  return value.name === 'Supercharge'
})

// { id: 2, name: 'Supercharge' }

findIndex

  • added in version 2.0

The findIndex method returns the index of the first item in the set satisfying the given predicate function. Returns -1 if no item matches the predicate function.

const users = Set.from([
  { id: 1, name: 'Marcus' },
  { id: 2, name: 'Supercharge' }
])

const index = users.findIndex((value, set) => {
  return value.name === 'Supercharge'
})
// 1

const index = users.findIndex((value, set) => {
  return value.name === 'Hello'
})
// -1

findLast

  • added in version 2.2

The findLast method returns the last item in the set matching the given predicate function.

const users = Set.from([
  { subscribed: true, name: 'Marcus' },
  { subscribed: true, name: 'Supercharge' }
])

const user = users.findLast(user => {
  return user.subscribed === true
})
// { id: 2, name: 'Supercharge' }

findLastIndex

  • added in version 2.2

The findLastIndex method returns the index of the last item in the set satisfying the given predicate function. Returns -1 if no item matches the predicate function.

const users = Set.from([
  { subscribed: true, name: 'Marcus' },
  { subscribed: true, name: 'Supercharge' }
])

const index = users.findLastIndex(user => {
  return user.subscribed === true
)
// 1

const index = users.findLastIndex((value, set) => {
  return value.name === 'Hello'
})
// -1

first

  • added in version 1.7

The first method returns the first item in the set or the first item matching the given predicate function:

const users = Set.from([
  { id: 1, name: 'Marcus' },
  { id: 2, name: 'Supercharge' }
  { id: 3, name: 'Albert' }
])

users.first()
// { id: 1, name: 'Marcus' }

users.first(user => {
  return user.id > 1
})
// { id: 2, name: 'Supercharge' }

users.first(user => {
  return user.id > 22
})
// undefined

flatMap

  • added in version 1.3

The flatMap method returns a new set instance, after applying the given transform function and collapsing the result (one level deep).

The transform function will be called once for each entry in the set in insertion order. The transform function receives the value, set arguments:

const users = Set.from([ 'Marcus', ['Supercharge'] ])

const names = users.map((value, set) => {
  return value
})
// Set ['Marcus', 'Supercharge']

flatten

  • added in version 1.3

The flatten method flattens the items in the set at a depth of 1.

const users = Set.from([ 'Marcus', ['Supercharge'] ]).flatten()

// Set ['Marcus', 'Supercharge']

forEach

  • added in version 1.0

The forEach method processes a given callback function once for each entry in the set in insertion order. The callback function receives the value, set arguments:

const names = Set.from(['Marcus', 'Supercharge'])

names.forEach(name => {
  console.log(name)
})

// 'Marcus'
// 'Supercharge'

has

  • added in version 1.0

The has method returns true if the given value is present in the set, otherwise false:

const users = new Set()

users
  .add('Marcus')
  .add('Supercharge')

users.has('Marcus')
// true

users.has('not-existent')
// false

includes

  • added in version 1.5

The includes method determines whether the set includes a given value or if it includes a value satisfying a given predicate function:

const set = Set.from([1, 2, 3, 4, 5])

set.includes(4)
// true

set.includes(num => {
  return num > 3
})
// true

intersect

  • added in version 2.2

The intersect method returns a set containing all items that are contained in all collections:

const ids = Set.from([1, 2, 3])

const intersection = ids.intersect(
  Set.from([2, 3]), [1, 3, 4, 5]
)
// Set [3]

isEmpty

  • added in version 1.0

The isEmpty method returns true if the set has no entries. Returns false if entries are present in the set:

const set = new Set()

set.isEmpty()
// true

set.add('Marcus')

set.isEmpty()
// false

isMissing

  • added in version 2.0

The isMissing method returns true if the given value is not present in the set, otherwise false:

const users = Set.from(['Marcus', 'Supercharge'])

users.isMissing('Marcus')
// false

users.isMissing('not-existent')
// true

join

  • updated in 1.9 to support a callback function to compose a seperator
  • updated in 1.8 to support an optional seperator
  • added in version 1.0

The join method returns a string of all items concatenated. By default, it uses a comma , for concatenation:

const set = Set.from([1, 2, 3])

set.join()
// '1,2,3'

You can provide a separator that will then be used for concatenation:

const set = Set.from([1, 2, 3])

set.join('; ')
// '1; 2; 3'

You may also provide a callback function to compose a separator for each item:

const set = Set.from([1, 2, 3])

set.join(name => {
  return `${name} -> `
})
// '1 -> 2 -> 3 ->'

isNotEmpty

  • added in version 1.0

The isNotEmpty method returns true if entries are present in the set. Returns false if the set is empty:

const set = new Set()

set.isNotEmpty()
// false

set.add('Marcus')

set.isNotEmpty()
// true

map

  • added in version 1.0

The map method returns a new set instance containing the results of the given transform function.

The transform function will be called once for each entry in the set, in order of insertion. The transform function receives the value, set arguments:

const users = Set()

users
  .add('Marcus')
  .add('Supercharge')

const names = users.map((value, set) => {
  return value
})

// Set ['Marcus', 'Supercharge']

reduce

  • added in version 1.6

The reduce method invokes reducer function on each item in the set, passing the result of the previous iteration to the subsequent iteration. The result is a reduced set to a single value:

const set = Set.from([1, 2, 3, 4, 5])

set.reduce((sum, value) => {
  return sum + value
}, 0)
// 15

The reduce method takes an initial value as a second argument. In the code snippet above, the initial value is 0. Using 5 as the initial value returns a different result:

const set = Set.from([1, 2, 3, 4, 5])

set.reduce((sum, value) => {
  return sum + value
}, 5)
// 20

size

  • added in version 1.0

The size method returns the number of entries in the set:

const set = Set.from(['Marcus', 'Supercharge'])

const size = set.size()
// 2

sort

  • added in version 3.0

The sort method returns the sorted set. You can sort a set containing only primitive values without a compare function:

const sorted = Set.from([4, 1, 37, 2, 1]).sort()
// [1, 1, 2, 4, 37]

The sort method accepts an optional compare function for custom sort operations. You’re receiving two elements in the compare function. The compare function determines the resulting order of items by it’s return value:

  • a negative value if the first argument is less than second argument
  • zero if they're equal
  • a positive value if the second argument is larger than the first argument

The elements are sorted in ascending order when omitting the compareFn:

Set.from([4, 1, 37, 2, 1]).sort((a, b) => {
  return b - a
})
// [37, 4, 2, 1, 1]

toArray

  • added in version 1.0

The toArray method returns an array containing the entries of the set.

const set = Set.from([1, 2, 3, 4])

const array = set.toArray()
// [1, 2, 3, 4]

values

  • added in version 1.0

The values method returns an iterator object of the values present in the set (in insertion order):

const users = Set.from(['Marcus', 'Supercharge'])

const valueIterator = users.values()

valueIterator.next().value
// 'Marcus'

valueIterator.next().value
// 'Supercharge'

You may also iterate through the values using a for..of loop:

const users = Set.from(['Marcus', 'Supercharge'])

for (const value of users.values()) {
  console.log(value)
}

// 'Marcus'
// 'Supercharge'