Browse Source

[refactor] Members instead of Closures

master
Muthu Kumar 6 years ago
parent
commit
a74ac5cdb3
  1. 190
      index.js
  2. 54
      package.json

190
index.js

@ -22,38 +22,39 @@ class InfiniteListItem {
* @memberof InfiniteListItem * @memberof InfiniteListItem
*/ */
constructor(list, value, index) { constructor(list, value, index) {
this.__list__ = list;
this.value = value; this.value = value;
this.index = index; this.index = index;
this.next = z => (!z ? list.get(index + 1) : list.get(index + z)); this.next = z => (!z ? this.__list__.get(index + 1) : this.__list__.get(index + z));
this.previous = z => (!z ? list.get(index - 1) : list.get(index - z)); this.previous = z => (!z ? this.__list__.get(index - 1) : this.__list__.get(index - z));
// Check if Symbol exists
if (typeof Symbol !== 'undefined' && Symbol.iterator) {
/**
* ES6 Symbol.iterator
* @returns {Iterable.<InfiniteListItem>}
*/
this[Symbol.iterator] = () => ({
next: () => ({
value: list.get(index + 1),
done: false
})
});
}
} }
}
// Check if environment supports Symbol
if (typeof Symbol !== 'undefined' && Symbol.iterator) {
/** /**
* toString method for pretty printing InfiniteListItem instance. * ES6 Symbol.iterator
* @returns {String} Decycled and beautified string * @returns {Iterable.<InfiniteListItem>}
* @memberof InfiniteListItem
*/ */
toString() { InfiniteListItem.prototype[Symbol.iterator] = () => ({
return ('InfiniteListItem [ .. ' + next: () => ({
stringify(this.value) + value: this.__list__.get(index + 1),
' .. ]') done: false
} })
});
} }
/**
* toString method for pretty printing InfiniteListItem instance.
* @returns {String} Decycled and beautified string
* @memberof InfiniteListItem
*/
InfiniteListItem.prototype.toString = function () {
return ('InfiniteListItem [ .. ' +
stringify(this.value) +
' .. ]');
};
class InfiniteList { class InfiniteList {
/** /**
* InfiniteList Constructor. * InfiniteList Constructor.
@ -68,73 +69,9 @@ class InfiniteList {
*/ */
constructor(start, next) { constructor(start, next) {
// Closure magic! this.__start__ = start;
let cache = []; this.__next__ = next;
let j = 0; this.__cache__ = [];
/**
* Get InfiniteListItem at index.
* @param {Number} index A non-negative integer representing index
* @returns {InfiniteListItem}
* @memberof InfiniteList
*/
this.get = function (index) {
// Validation
if (
// i is a non-zero falsy value, or is negative
(isNonZeroFalsy(index) || index < 0)
|| !areNumbers(index)
) return;
//TODO: Cache limiting. (Removed for unexpected behaviour)
// Initializing first item if it doesn't exist
if (!cache[0]) cache[0] = start;
// If index were to be infinity, value and index are infinity
if (index === Infinity) return new InfiniteListItem(this, Infinity, Infinity);
// If index exists in cache, return the value
if (index in cache) return new InfiniteListItem(this, cache[index], index);
// If i doesn't exist in cache
if (!(index in cache)) {
if (cache.length <= index && (cache.length - 1) in cache)
while (cache.length <= index)
cache[cache.length] = next(
cache[cache.length - 1],
cache[cache.length - 2]
);
}
return new InfiniteListItem(this, cache[index], index);
}
/**
* Clear cache manually.
* Forces destroy reference to cache, and creates a new cache.
* Old cache will be GC'd.
* @returns {undefined}
* @memberof InfiniteList
*/
this.clearCache = () => (cache = [], undefined);
// Check if Symbol exists
if (typeof Symbol !== 'undefined' && Symbol.iterator) {
/**
* ES6 Symbol.iterator
* @returns {Iterable.<InfiniteListItem>}
* @memberof InfiniteList
*/
this[Symbol.iterator] = function () {
return {
next: () => ({
value: this.get(j++),
done: false
})
};
};
}
if(typeof Proxy !== 'undefined') if(typeof Proxy !== 'undefined')
return new Proxy(this, { return new Proxy(this, {
@ -162,6 +99,77 @@ class InfiniteList {
} }
} }
// Check if Symbol exists
if (typeof Symbol !== 'undefined' && Symbol.iterator) {
/**
* ES6 Symbol.iterator
* @returns {Iterable.<InfiniteListItem>}
* @memberof InfiniteList
*/
InfiniteList.prototype[Symbol.iterator] = function () {
let j = 0;
return {
next: () => ({
value: this.get(j++),
done: false
})
};
};
}
/**
* Get InfiniteListItem at index.
* @param {Number} index A non-negative integer representing index
* @returns {InfiniteListItem}
* @memberof InfiniteList
*/
InfiniteList.prototype.get = function (index) {
// Validation
if (
// i is a non-zero falsy value, or is negative
(isNonZeroFalsy(index) || index < 0)
|| !areNumbers(index)
) return;
const start = this.__start__;
const next = this.__next__;
const cache = this.__cache__;
//TODO: Cache limiting. (Removed for unexpected behaviour)
// Initializing first item if it doesn't exist
if (!cache[0]) cache[0] = start;
// If index were to be infinity, value and index are infinity
if (index === Infinity) return new InfiniteListItem(this, Infinity, Infinity);
// If index exists in cache, return the value
if (index in cache) return new InfiniteListItem(this, cache[index], index);
// If i doesn't exist in cache
if (!(index in cache)) {
if (cache.length <= index && (cache.length - 1) in cache)
while (cache.length <= index)
cache[cache.length] = next(
cache[cache.length - 1],
cache[cache.length - 2]
);
}
return new InfiniteListItem(this, cache[index], index);
}
/**
* Clear cache manually.
* Forces destroy reference to cache, and creates a new cache.
* Old cache will be GC'd.
* @returns {undefined}
* @memberof InfiniteList
*/
InfiniteList.prototype.clearCache = function () {
this.__cache__ = [];
};
/** /**
* Takes a given number of elements from the InfiniteList. * Takes a given number of elements from the InfiniteList.
* @param {Number} from Number of elements or starting index * @param {Number} from Number of elements or starting index

54
package.json

@ -1,28 +1,28 @@
{ {
"name": "@codefeathers/infinity", "name": "@codefeathers/infinity",
"version": "0.3.0", "version": "0.4.0",
"description": "Infinitely generating linked list with memoisation (or an n-generator)", "description": "Infinitely generating linked list with memoisation (or an n-generator)",
"main": "es5/infinity.min.js", "main": "es5/infinity.min.js",
"scripts": { "scripts": {
"build": "./build.sh", "build": "./build.sh",
"test:es6": "NODE_ENV=development jasmine", "test:es6": "NODE_ENV=development jasmine",
"test:es5": "NODE_ENV=production npm run build && jasmine", "test:es5": "NODE_ENV=production npm run build && jasmine",
"test": "npm run test:es6 && npm run test:es5", "test": "npm run test:es6 && npm run test:es5",
"prepublishOnly": "npm test" "prepublishOnly": "npm test"
}, },
"keywords": [ "keywords": [
"infinite", "infinite",
"list", "list",
"data structure", "data structure",
"datatypes", "datatypes",
"generators" "generators"
], ],
"author": "Muthu Kumar <@MKRhere> (https://mkr.pw)", "author": "Muthu Kumar <@MKRhere> (https://mkr.pw)",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"babel-cli": "^6.26.0", "babel-cli": "^6.26.0",
"babel-preset-env": "^1.7.0", "babel-preset-env": "^1.7.0",
"browserify": "^16.2.2", "browserify": "^16.2.2",
"uglify-js": "^3.3.25" "uglify-js": "^3.3.25"
} }
} }
Loading…
Cancel
Save