DEV Community

loading...
Cover image for My first npm package is about sets

My first npm package is about sets

Dóka Balázs
Angular and React specialist
・3 min read

Hi! This is my first DEV post. Recently I had to use some sets in my Javascript code that needed to contain objects as items. The problem is the browser Set object compares their items by equality. So I decide to create a micro-library in which you can use sets that can handle all the set operation comaprinf the items with an id as a key.

Let me introduce you to the library SmartSet

Installation

If you want to use my library you can install it easily by npm or yarn.

npm install smart-set

yarn add smart-set
Enter fullscreen mode Exit fullscreen mode

Creation and operations

The SmartSet class extends the Set class, so every member of Set is available, and compatible with the Set interface.

Constructor

SmartSet has two template paramters:

  • T is the type of items
  • ID is the type of the key (must be primitive)

SmartSet constructor requires a function that determines the id of an item which should be unique and primitive. The second parameter is a list of items of T, which will be the starting data of the set. These items will be unique in the set.

import { SmartSet } from "smart-set";

interface Data { id: string };

const mySet = new SmartSet<Data, string>(item => item.id, [{ id: 'id1' }, { id: 'id2' }, { id: 'id1' }]);
Enter fullscreen mode Exit fullscreen mode

Addition

The add(item: T) and addAll(items: T[]) functions add item(s) to the set uniquely by the given id function.

mySet.add({ id: 'id3' });
mySet.add({ id: 'id1' });
mySet.addAll([{ id: 'id1' }, { id: 'id4' }, { id: 'id5' }]);
Enter fullscreen mode Exit fullscreen mode

Deletion

The delete(item: T) and deleteId(id: ID) functions delete an item by the given id function.
The clear() function deletes all elements.

mySet.delete({ id: 'id3' });
mySet.deleteId('id1');
mySet.clear();
Enter fullscreen mode Exit fullscreen mode

Containment

The has(item: T): boolean and hasId(id: ID): boolean check whether an item is part of the set by the given id function.

mySet.has({ id: 'id3' }) === false;
mySet.hasId('id1') === true;
Enter fullscreen mode Exit fullscreen mode

Iteration

SmartSet is iterable and has the keys(): IterableIterator<ID>, values(): IterableIterator<T> and entries(): IterableIterator<[ID, T]> functions for iterating the set. Keys are the values of the ID type.

const mySet = new SmartSet<Data, string>(item => item.id, [{ id: 'id1' }, { id: 'id2' }, { id: 'id3' }]);

[...mySet.keys()] === ['id1', 'id2', 'id3'];

[...mySet.values()] === [{ id: 'id1' }, { id: 'id2' }, { id: 'id3' }];

[...mySet.entries()] === [['id1', { id: 'id1' }], ['id2', { id: 'id2' }], ['id3', { id: 'id3' }]];

[...mySet] === [{ id: 'id1' }, { id: 'id2' }, { id: 'id3' }];

mySet.forEach((value, key, set) => { /* something with the key, value and set */ })
Enter fullscreen mode Exit fullscreen mode

Set operations

SmartSet has some set operation that corresponds to the mathematics representation. These operations are immutable, so they return a new SmartSet instance and does not modify the original set. The methods accept regular Set objects, because it runs the ID creation function on the items.

union(other: Set<T>): SmartSet<T, ID>

intersection(other: Set<T>): SmartSet<T, ID>

difference(other: Set<T>): SmartSet<T, ID>

symmetricDifference(other: Set<T>): SmartSet<T, ID>

let result;
const setA = new SmartSet<Data, string>(item => item.s, [ { s: '1' }, { s: '2' } ]);
const setB = new SmartSet<Data, string>(item => item.s, [ { s: '1' }, { s: '3' } ]);

result = setA.union(setB); //  [ { s: '1' }, { s: '2' }, { s: '3' } ]
result = setA.intersection(setB); //  [ { s: '1' } ]
result = setA.difference(setB); //  [ { s: '2' } ]
result = setB.difference(setA); //  [ { s: '3' } ]
result = setA.symmetricDifference(setB); //  [ { s: '2' }, { s: '3' } ]
Enter fullscreen mode Exit fullscreen mode

Closing words

As I am new to library publishing and open source world it would be a huge help if you could take a look at my source code or report an issue at the repository of the package at github. Thanks for reading my first post.

Discussion (3)

Collapse
okikio profile image
Okiki

Awesome, I made something similar but for Maps instead it's called @okikio/manager

Collapse
dbalazs97 profile image
Dóka Balázs Author

Wow nice library, I was also thinking about creating the “smart” data structures package family.

Collapse
okikio profile image
Okiki

Cool, that would be awesome. One thing I noticed is that your smartsets library isn't using native sets is there a reason for that.