Created
April 29, 2020 15:48
-
-
Save pravic/047b74611f2be23ba0704f1c912b2278 to your computer and use it in GitHub Desktop.
Extending TIScript collections
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
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator | |
// https://fitzgen.github.io/wu.js/ | |
class Iterator | |
{ | |
this var m = []; | |
function this(iterable) { | |
for(var k in iterable) { | |
this.m.push(k); | |
} | |
} | |
/// Converts an iterable to an Array. | |
function toArray() { | |
return this.m; | |
} | |
/// Applies the given function to each item in the iterable and yields the result. | |
function map(fn, thisArg=undefined) { | |
return this.m.map(fn, thisArg); | |
} | |
/// Yield only the items from the iterable for which `fn(item)` is truthy. | |
function filter(fn, thisArg=undefined) { | |
return this.m.filter(fn, thisArg); | |
} | |
/// Yield the first `n` items from the iterable. | |
function take(n) { | |
return new Iterator(this.m.slice(0, n)); | |
} | |
/// Drop the first `n` items from the iterable. | |
function drop(n) { | |
return new Iterator(this.m.slice(n)); | |
} | |
/// Reduce the iterable from left to right with the binary function `fn`. | |
/// If `initial` is supplied, start with that value, | |
/// otherwise use the first value in the iterable. | |
function reduce(fn, initial=undefined) { | |
return initial ? this.m.reduce(fn, initial) : this.m.reduce(fn); | |
} | |
/// Return `true` if `fn(item)` is truthy for any of the items in the iterable, | |
/// otherwise return `false`. | |
function some(fn, thisArg=undefined) { | |
return this.m.some(fn, thisArg); | |
} | |
/// Return `true` if `fn(item)` is truthy for every item in the iterable, | |
/// otherwise return `false`. | |
function every(fn, thisArg=undefined) { | |
return this.m.every(fn, thisArg); | |
} | |
/// Return the first item from the iterable for which `fn(item)` is truthy. | |
/// If no item is found, `undefined` is returned. | |
function find(fn, thisArg=undefined) { | |
return this.m.find(fn, thisArg); | |
} | |
/// Call `fn(item)` for each item in the iterable. | |
function forEach(fn) { | |
for (var v in this.m) { | |
fn(v); | |
} | |
} | |
// | |
// wu.js methods: | |
// | |
/// For each item in the iterable, yield a pair `[item, index]`. | |
function enumerate() { | |
var a = new Array(this.m.length); | |
for(var i = 0; i < this.m.length; i++) { | |
a[i] = [i, this.m[i]]; | |
} | |
return new Iterator(a); | |
} | |
/// Return the nth item from the iterable. | |
/// If `n` is out of bounds, `undefined` is returned. | |
function nth(n) { | |
return (n >= 0 && n < this.m.length) ? this.m[n] : undefined; | |
} | |
/// Accumulate items from the iterable into arrays of size `n` and yield each array. | |
function chunk(n) { | |
var a = new Array(this.m.length); | |
for(var i = 0; i < this.m.length; i += n) { | |
a[i] = this.m.slice(i, i + n); | |
} | |
return new Iterator(a); | |
} | |
} | |
/** The Map object holds key-value pairs | |
and remembers the original insertion order of the keys. | |
Any value (both objects and primitive values) may be used as either a key or a value. | |
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map | |
*/ | |
class Map | |
{ | |
this var m = {}; | |
/// Returns the number of key/value pairs in the `Map` object. | |
get size() { return this.m.length; } | |
/// The `Map()` constructor creates `Map` objects. | |
/// | |
/// `args`: An `Array` or other iterable object whose elements are key-value pairs. | |
/// Each key-value pair is added to the new `Map`. | |
function this(args=undefined) { | |
// args: [[key,value]] | |
if(args) { | |
// avoid partial construction on exceptions | |
var m = {}; | |
for(var pair in args) { | |
m[pair[0]] = pair[1]; | |
} | |
this.m = m; | |
} | |
} | |
/// Removes all key-value pairs from the Map object. | |
function clear() { | |
this.m = {}; | |
} | |
/// Returns true if an element in the Map object existed and has been removed, | |
/// or false if the element does not exist. | |
function delete(key) { | |
if(!this.has(key)) { | |
return false; | |
} else { | |
delete m[key]; | |
return true; | |
} | |
} | |
/// Returns a new Iterator object that contains an array of `[key, value]` | |
/// for each element in the Map object in insertion order. | |
function entries() { | |
var i = 0; | |
var a = new Array(this.m.length); | |
for(var(k,v) in this.m) { | |
a[i++] = [k,v]; | |
} | |
return a; | |
} | |
/// Returns a new Iterator object that contains the keys | |
/// for each element in the Map object in insertion order. | |
function keys() { | |
return Object.keys(this.m); | |
} | |
/// Returns a new Iterator object that contains the **values** for each element | |
/// in the `Map` object in insertion order. | |
function values() { | |
// return this.entries().map(:a: a[1]); | |
var i = 0; | |
var a = new Array(this.m.length); | |
for(var(k,v) in this.m) { | |
a[i++] = v; | |
} | |
return a; | |
} | |
/// Returns the value associated to the `key`, or `undefined` if there is none. | |
function get(key) { | |
return this.m[key]; | |
} | |
/// Returns a boolean asserting whether a value has been associated to the `key` in the `Map` object or not. | |
function has(key) { | |
return this.m[key] !== undefined; | |
} | |
/// Sets the `value` for the `key` in the `Map` object. | |
/// Returns the `Map` object. | |
function set(key, value) { | |
this.m[key] = value; | |
return this; | |
} | |
/// Calls `callbackFn` once for each key-value pair present in the `Map` object, | |
/// in insertion order. | |
/// If a `thisArg` parameter is provided to `forEach`, | |
/// it will be used as the `this` value for each callback. | |
function forEach(callbackFn, thisArg=undefined) { | |
for(var(k,v) in this.m) { | |
callbackFn.apply(thisArg, [k,v, this]); | |
} | |
} | |
} | |
/** The `Set` object lets you store unique values of any type, | |
whether primitive values or object references. | |
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set | |
*/ | |
class Set: Map | |
{ | |
/// The `Set()` constructor creates `Set` objects. | |
/// | |
/// `args`: An `Array` or other iterable object whose elements are key-value pairs. | |
/// Each key-value pair is added to the new `Map`. | |
function this(args=undefined) { | |
// args: [key] | |
if(args) { | |
// avoid partial construction on exceptions | |
var m = {}; | |
for(var key in args) { | |
m[key] = key; | |
} | |
this.m = m; | |
} | |
} | |
/// Appends value to the `Set` object. Returns the `Set` object. | |
function add(value) { | |
this.m[value] = value; | |
return this; | |
} | |
// override | |
function set(value) { | |
throw "Use `Set.add(value)` instead."; | |
this.m[value] = value; | |
return this; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment