Created
August 20, 2018 10:52
-
-
Save shevchenkobn/e3119088465c9022a080c8241e410f60 to your computer and use it in GitHub Desktop.
A Sorted Collection in vanilla es5 with write protection via function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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