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
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' }]);
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' }]);
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();
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;
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 */ })
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' } ]
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.
Top comments (3)
Awesome, I made something similar but for Maps instead it's called @okikio/manager
Wow nice library, I was also thinking about creating the “smart” data structures package family.
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.