Skip to content

Instantly share code, notes, and snippets.

@shevchenkobn
Created August 20, 2018 10:52
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 shevchenkobn/e3119088465c9022a080c8241e410f60 to your computer and use it in GitHub Desktop.
Save shevchenkobn/e3119088465c9022a080c8241e410f60 to your computer and use it in GitHub Desktop.
A Sorted Collection in vanilla es5 with write protection via function
function SortedCollection(comparatorOrInstance, iterable) {
if (!(this instanceof SortedCollection)) {
return new SortedCollection(comparatorOrInstance, iterable);
}
if (comparatorOrInstance instanceof SortedCollection) {
return new SortedCollection(comparatorOrInstance._comparator, comparatorOrInstance._arr);
} else if (!(comparatorOrInstance instanceof Function)) {
throw new TypeError('Comparator (first argument) must be provided!');
}
const arr = [...iterable].sort(comparatorOrInstance);
const self = _getterFunction.bind(arr);
self.__proto__ = SortedCollection.prototype;
self._arr = [...iterable].sort(comparatorOrInstance);
self._comparator = comparatorOrInstance;
return self;
}
function methodsFactory(value, notApply = false) {
return {
value: notApply ? value : function() {
return value.apply(this._arr, arguments);
},
configurable: false,
enumerable: false,
writable: true
};
}
SortedCollection.prototype = Object.create(Object.prototype, {
slice: methodsFactory(Array.prototype.slice),
forEach: methodsFactory(Array.prototype.forEach),
at: methodsFactory(_getterFunction),
clone: methodsFactory(function() {
return new SortedCollection(this);
}, true),
add: methodsFactory(function(value) {
if (this._comparator(this._arr[0], value) >= 0) {
this._arr.unshift(value);
return this;
} else if (this._comparator(this._arr[this._arr.length - 1], value) <= 0) {
this._arr.push(value);
return this;
}
for (let i = 0; i < this._arr.length; i++) {
if (this._comparator(this._arr[0], value) >= 0) {
this._arr.splice(i, 0, value);
return this;
}
}
}, true)
});
function _getterFunction(i) {
return this[i];
}
//////
const list = SortedCollection((a, b) => a - b, [1, 2, 3]);
console.log(list(1));
console.log(list.at(0));
console.log(list(3));
console.log(list.at(4));
console.log(list.slice());
console.log(list instanceof Function && 'not a function' || 'function');
console.log(list instanceof SortedCollection && ' a collection');
const clone = list.clone();
console.log(clone, clone !== list);
console.log(clone.add(-1), list);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment