Skip to content

Instantly share code, notes, and snippets.

@TheSeamau5
Created April 19, 2016 18:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheSeamau5/7aa631a77c31f79467c1f16374f74f78 to your computer and use it in GitHub Desktop.
Save TheSeamau5/7aa631a77c31f79467c1f16374f74f78 to your computer and use it in GitHub Desktop.
Selection List in Javascript using Immutable
import Immutable from 'immutable';
/* Selection List Data Structure */
class SelectionList {
constructor(list) {
if (list.length > 0) {
this._previous = new Immutable.Stack();
this._selected = list[0];
this._next = new Immutable.Stack(list.splice(1));
} else {
throw new Error('Selection list must include at least one element');
}
}
toArray() {
return this._previous.toSeq()
.reverse()
.toArray()
.concat(this._selected)
.concat(this._next.toSeq().toArray());
}
map(f) {
const previousSize = this._previous.size;
const previous = new Immutable.Stack(this._previous.toSeq().reverse().map(f).reverse());
const selected = f(this._selected, previousSize);
const next = new Immutable.Stack(this._next.toArray().map((x, index) => f(x, index + previousSize + 1)));
return makeSelectionList(previous, selected, next);
}
next() {
if (this._next.size > 0) {
const previous = this._previous.push(this._selected);
const selected = this._next.peek();
const next = this._next.pop();
return makeSelectionList(previous, selected, next);
} else {
return this;
}
}
previous() {
if (this._previous.size > 0) {
const selected = this._previous.peek();
const previous = this._previous.pop();
const next = this._next.push(this._selected);
return makeSelectionList(previous, selected, next);
} else {
return this;
}
}
get selectedIndex() {
return this._previous.size;
}
goto(index) {
const currentIndex = this.selectedIndex;
if (index === currentIndex) {
return this;
} else if (currentIndex < index && this._next.size > 0) {
return this.next().goto(index);
} else if (currentIndex > Math.max(0, index)) {
return this.previous().goto(index);
} else {
return this;
}
}
toObject() {
return {
previous: this._previous.toArray(),
selected: this._selected,
next: this._next.toArray()
};
}
updateSelected(f) {
return makeSelectionList(
this._previous,
f(this._selected),
this._next
);
}
}
const SelectionListPrototype = SelectionList.prototype;
const makeSelectionList = (previous, selected, next) => {
let selectionList = Object.create(SelectionListPrototype);
selectionList._previous = previous;
selectionList._selected = selected;
selectionList._next = next;
return selectionList;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment