Skip to content

FancySet & ImmutableFancySet — extensions of JavaScript's built-in Set class.

License

Notifications You must be signed in to change notification settings

TehShrike/FancySet

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 

Repository files navigation

FancySet & ImmutableFancySet

TL;DR

FancySet extends Set to include all the bells and whistles one often needs when working with sets.

ImmutableFancySet extends FancySet with new versions of add and delete that always return a new set (instead of mutating the current one).

If you create a new ImmutableFancySet from an existing ImmutableFancySet. For instance:

let a = new ImmutableFancySet([1,2,3]);
b = a.add(4,5);
a // [1,2,3]
b // [1,2,3,4,5]

the new IFS can tell you if it's equal to the original IFS it was based on.

Example:

let a = new ImmutableFancySet([1,2,3]); // [1,2,3]  does not point to an IFS
b = a.add(4); // [1,2,3,4]  points to a
c = b.add(5); // [1,2,3,4,5]  points to a
d = c.add(6); // [1,2,3,4,5,6]  points to a
e = d.add(7); // [1,2,3,4,5,6,7]  points to a

              // NOTICE! these do not point back to the one before, they point back to the very first.

e.equalToOriginal() // false

f = e.delete(7,6,5,4);

f.equalToOriginal(); // true

This ^^^ feature is why ImmutableFancySet (and FancySet) were made. I needed something that would play nice with react state (immutable), but that also was aware of the very first state.

README

FancySet

FancySet provides the following methods:

isSuperSet
union
intersection
symmetricDifference
difference, 
equal 
equalToOriginal
hasChanged
original

isSuperSet, union, intersection, symmetricDifference, and difference are taken, with some modification, from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#Implementing_basic_set_operations)

equal builds off of those.

These methods do exactly what you think. I'll explain equalToOriginal, hasChanged, and original at the end.

ImmutableFancySet

ImmutableFancySet overrides all of the mutating methods of set—add, delete, and clear—with non-mutating versions, and provides a few more functions which give one a way to know whether or not derived IFSes have deviated from the first one.

ImmutableFancySet provides the following methods:

add
delete
clear
isTheOriginal
equalToOriginal
hasChanged
original

Add

Unlike Set's version of add, IFS's add can take multiple arguments, allowing you to add multiple items at once. Add does not mutate the IFS.

let a = new ImmutableFancySet(); // a new empty IFS
a.add(5,6,7); // a new IFS with these values: [5,6,7]
a; // empty IFS

but instead returns a new IFS.

let a = new ImmutableFancySet([1,2,3]);
let b = a.add(5,6,7);
a; // [1,2,3]
b; // [1,2,3,5,6,7]

Delete

Like add, delete can take multiple arguments, and, like add, does not mutate the IFS.

delete returns a set, unlike Set's delete which returns true or false.

Example:

let a = new ImmutableFancySet([1,2,3]);
let b = a.delete(2,3);
a; // [1,2,3]
b; // [1]

Clear

clear is simply undefined for IFSes.


originalImmutableFancySet property

When creating an IFS from another IFS.

let a = new ImmutableFancySet([1,2,3]);
b = new ImmutableFancySet(a); // new IFS based off of 'a'
c = a.add(4); // new IFS based off of 'a'

The new IFS gets a property originalImmutableFancySet, which points to the IFS that the IFS was made from. If IFS x is made from IFS y, and y has the property originalImmmutableFancySet, x's originalImmutableFancySet will be set to y's originalImmutableFancySet.

Example:

let a = new ImmutableFancySet([1,2,3]); // no oIFS (made from an array, not an IFS)
b = a.add(4); oIFS == a
c = b.add(5); oIFS still == a
d = c.add(6); oIFS is, yes, still == a

The purpose of this was to have a set that played well with React state (didn't mutate), but, kept track of whether or not it had changed from the original set.

The following methods are tools for working with oIFS

isTheOriginal
equalToOriginal
hasChanged
original

isTheOriginal

Returns true if the IFS doesn't have the property orignalImmutableFancySet.


equalToOriginal

This example from above illustrates how equalToOriginal works:

Example:

let a = new ImmutableFancySet([1,2,3]); // [1,2,3]  does not point to an IFS
b = a.add(4);
c = b.add(5);
d = c.add(6);
e = d.add(7);

e.equalToOriginal() // false

f = e.delete(7,6,5,4);

f.equalToOriginal(); // true

hasChanged

The negation of equalToOriginal. This method is why ImmutableFancySet (and FancySet) were made.

Imagine getting a set from the backend that you store in react state.

The user can add and delete from the set, and you want to provide a save button (save current set state to back-end database) that is enabled only if the current set is different from the original set received from the back-end. ImmutableFancySet is a datatype that can do all of that for you.

<button disabled={!set.hasChanged} ... >

however it's easier to read for you

<button disabled={set.equalToOriginal} ... >

original

Returns either the property originalImmutableFancySet or the ImmutableFancySet itself.


FancySet's equalToOriginal, hasChanged, and original

FancySet has analogous equalToOriginal, hasChanged, and original methods that work for a mutatey FancySet.

let a = new ImmutableFancySet([1,2,3]); // [1,2,3]  does not point to an IFS
a.add(4);
a.add(5);
a.add(6); // notice: FancySet uses Set's add method (1 arg at a time)

a.equalToOriginal() // false

a.delete(6);
a.delete(5);
a.delete(4);

a.equalToOriginal(); // true

(These use the originalFancySet property.)

About

FancySet & ImmutableFancySet — extensions of JavaScript's built-in Set class.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 100.0%