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:
add all any at clear concat count delete filter find findIndex findLast findLastIndex first flatMap flatten forEach has includes intersect isEmpty isNotEmpty isMissing join map of reduce size sort toArray values
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'