commit 48c60f0b1f2146c1475dd68d0eb5b81fb1d803dd Author: Muthu Kumar Date: Tue May 15 10:23:24 2018 +0530 init diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..dd2b5af --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Launch Program", + "program": "${workspaceFolder}/example.js" + } + ] +} \ No newline at end of file diff --git a/example.js b/example.js new file mode 100644 index 0000000..b8652b1 --- /dev/null +++ b/example.js @@ -0,0 +1,27 @@ +const infiniteList = require('.'); + +const increment = i => i + 2; +const infinite = infiniteList.create(0, increment, 10); + +// infinite; +console.log(infinite.top()) +console.log(infinite.last()) + +console.log(infinite.get(5)) +console.log(infinite.get(5)) +console.log(infinite.get(6)) +console.log(infinite.get(14).next()) + +console.log(infinite.toString()) +console.log(infinite.top().next().next().toString()) + +console.log(infinite.take(5)) + +const gen = infinite[Symbol.iterator]; +gen(); + +for(let i of infinite) { + // if(i.index > 100) break; + // console.log(infinite.get(5).value); + console.log(i.value.toString()); +} diff --git a/index.js b/index.js new file mode 100644 index 0000000..68cae05 --- /dev/null +++ b/index.js @@ -0,0 +1,124 @@ +const always = x => _ => x; + +const infiniteList = { + /** + * InfiniteList Constructor. Iterates infinitely until index value is found. + * + * @param {any} start + * @param {any} next + * @param {any} limit + * @returns + */ + create (start, next, limit) { + + // Closure magic! + const cache = []; + let j = 0; + + // Get list item of index i + function get(i) { + + // Validation + if( + // i is a falsy value except 0 + (!i && i !== 0) + // is not a number + || (typeof i !== 'number') + // is... not a number + || Number.isNaN(i) + ) return; + + // Cache limiting. If cache becomes larger + // than limit, deletes non-empty first item + //TODO: FIX: Does not minCache is always 1, + // and cache length doesn't decrease more than 1 + let minCache; + if (cache.length > (limit || 10000)) + for (const cacheIndex in cache) { + delete cache[cacheIndex]; + minCache = cacheIndex + 1; + break; + } + + // Initializing first item if it doesn't exist + if(!cache[0]) cache[0] = start; + + // Create returnable object + const obj = { + next: () => this.get(i+1), + previous: () => this.get(i - 1), + [Symbol.iterator]: () => ({ + next: () => ({ + done: false, + value: this.get(i+1) + }) + }), + toString: () => { + const val = get(i).value; + return ( 'InfiniteLinkedListItem [ ..., ' + + ((typeof val === 'object' && val !== null) + ? JSON.stringify(val, null, 2) + : val.toString()) + + ', ... ]' ) + } + } + + // If index were to be infinity, value and index are infinity + if(i === Infinity) { + obj.value = Infinity; + obj.index = Infinity; + return obj; + } + + // If index exists in cache, return the value + if(i in cache) { + obj.value = cache[i]; + obj.index = i; + return obj; + } + + // If i doesn't exist in cache // Only works in forward + //TODO: FIX + if(!(i in cache)) { + if(cache.length <= i && (cache.length - 1) in cache) + while (cache.length <= i) + cache[cache.length] = next(cache[cache.length - 1]); + } + obj.value = cache[i]; + obj.index = i; + return obj; + } + + const take = (from, to) => { + const arr = []; + let source, target; + if(!to) { source = 0; target = from; } + else ({ from: source, to: target} = { from, to }); + for(let i = source; i < target; i ++) { + arr.push(get(i)); + }; + return arr; + }; + + top = function () { return this.get(0) }; + end = function () { return this.get(Infinity) }; + const returns = { + get, + take, + top, + first: top, + end, + last: end, + [Symbol.iterator]: () => ({ + next: () => ({ + done: false, + value: get(j++) + }) + }), + toString: () => 'InfiniteLinkedList [ ' + take(0, 10).map(x => (' ' + x.value.toString())) + ' ... ]' + }; + return returns; + } +} + +module.exports = infiniteList; diff --git a/package.json b/package.json new file mode 100644 index 0000000..0a9d504 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "@codefeathers/infinite", + "version": "0.1.0", + "description": "Infinitely generating linked list with memoisation (or an n-generator)", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "infinite", + "list", + "data structure", + "datatypes", + "generators" + ], + "author": "Muthu Kumar <@MKRhere> (https://mkr.pw)", + "license": "MIT" +}