Comparing version 0.1.0 to 0.1.1
136
adts.d.ts
declare module "adts" { | ||
/** | ||
Bag: a multiset; i.e., a Set with counts. The underlying datatype | ||
is a object, `._element_object`. The effective default of members | ||
of `._element_object` is 0. Being undefined, having a value of undefined, | ||
null, false, etc., is all equivalent to having a 0 count. | ||
`Bag()` and `new Bag()` both return an empty bag. | ||
*/ | ||
class Bag { | ||
/** | ||
Bag: a multiset; i.e., a Set with counts. The underlying datatype | ||
is a object, `._element_object`. The effective default of members | ||
of `._element_object` is 0. Being undefined, having a value of undefined, | ||
null, false, etc., is all equivalent to having a 0 count. | ||
`Bag()` and `new Bag()` both return an empty bag. | ||
*/ | ||
private _element_object; | ||
constructor(elements?: string[]); | ||
} | ||
} | ||
declare module "adts" { | ||
class Set { | ||
/** | ||
S = Set: a helper around an object with keys that represent elements in the set. | ||
The values of the object are all true; they do not really matter. | ||
This object is available at the private member `._element_object`. | ||
/** new Set(elements?: string[]) | ||
S(), S([]), new S(), and new S([]) will all return the empty set. | ||
Set is an abstract data type supporting methods like .add(), .merge(), | ||
.contains(), and .equals(). It is implemented by an object with keys that | ||
represent elements in the set. The values of the object are all boolean true's; | ||
the value does not matter, only their presence does. | ||
*/ | ||
All elements are coerced to strings by object index notation. | ||
*/ | ||
class Set { | ||
private _element_object; | ||
/** Create a new Set, optionally initializing it with an Array of strings */ | ||
constructor(elements?: string[]); | ||
_add(element: string): void; | ||
/** Clone this set, returning the copy. | ||
* [immutable] */ | ||
clone(): Set; | ||
/** Return an unordered Array of strings representing this Set. | ||
* [immutable] */ | ||
toJSON(): string[]; | ||
/** Add a single element to this set. | ||
* [mutable, chainable] */ | ||
_add(element: string): Set; | ||
/** Add multiple elements to this set. | ||
* [mutable, chainable] */ | ||
_addArray(elements: string[]): Set; | ||
/** Add all elements from another Set. | ||
* [mutable, chainable] */ | ||
_addSet(other: Set): Set; | ||
/** Remove a single element from this set. No-op if the element doesn't exist. | ||
* [mutable, chainable] */ | ||
_remove(element: string): void; | ||
/** Remove multiple elements from this set. | ||
* [mutable, chainable] */ | ||
_removeArray(elements: string): Set; | ||
/** Remove all elements from another Set. | ||
* [mutable, chainable] */ | ||
_removeSet(other: Set): Set; | ||
/** Return a new Set representing the union of this set and the given | ||
* element. | ||
* [immutable, chainable] */ | ||
add(element: string): Set; | ||
_merge(other_set: Set): void; | ||
_remove(element: string): void; | ||
equal(other_set: Set): boolean; | ||
contains(element: any): boolean; | ||
toArray(): string[]; | ||
/** Return a new Set representing the union of this set and the given | ||
* elements. | ||
* [immutable, chainable] */ | ||
addArray(elements: string[]): Set; | ||
/** Return a new Set representing the union of this set and another set. | ||
* [immutable, chainable] */ | ||
addSet(other: Set): Set; | ||
/** Return a new Set representing the subtraction of the given element from | ||
* this Set. | ||
* [immutable, chainable] */ | ||
remove(element: string): void; | ||
/** Return a new Set representing the subtraction of the given elements from | ||
* this Set. | ||
* [immutable, chainable] */ | ||
removeArray(elements: string): Set; | ||
/** Return a new Set representing the subtraction of the given Set from | ||
* this Set. | ||
* [immutable, chainable] */ | ||
removeSet(other: Set): Set; | ||
/** Pairwise set comparison. Return false at the first mismatch, otherwise | ||
* return true. | ||
* | ||
* new Set([1, 4, 9]).equal(new Set([9, 4, 1])) == true | ||
* new Set(['a', 'b', 'z']).equal(new Set(['a', 'b'])) == false | ||
* [immutable] */ | ||
equals(other: Set): boolean; | ||
/** Check if the given element is contained in this set. */ | ||
contains(element: string): boolean; | ||
/** Simply . */ | ||
size: number; | ||
/** Compare an Array of Sets, returning true if they're all equal. | ||
*/ | ||
static equal(sets: Set[]): boolean; | ||
/** Return true if all the given Sets contain the given element. | ||
* Returns false on the first mismatch. */ | ||
static contain(sets: Set[], element: string): boolean; | ||
/** Return a new Set that contains all the elements from the given Sets. | ||
* [immutable] */ | ||
static union(sets: Set[]): Set; | ||
static equal(sets: Set[]): boolean; | ||
/** Return a new Set representing the intersection of all given Sets. | ||
* [immutable] */ | ||
static intersection(sets: Set[]): Set; | ||
} | ||
} | ||
declare module "adts" { | ||
/** new Stack<T>(elements?: T[]) | ||
Basically a simplified Array wrapper, with Stack#bottom and Stack#top getters. | ||
When initialized with an Array, the last element in the array will be the top of | ||
the Stack. The constructor's elements argment is optional, and defaults to an | ||
empty array. | ||
*/ | ||
class Stack<T> { | ||
/** Stack is mostly an impoverished Array wrapper, | ||
but with a .top helper */ | ||
private _array; | ||
constructor(); | ||
constructor(elements?: T[]); | ||
/** Stack#length | ||
Returns size of stack. | ||
*/ | ||
length: number; | ||
push(item: T): void; | ||
/** Stack#push(element) | ||
Returns size of stack after adding element. | ||
*/ | ||
push(element: T): number; | ||
pop(): T; | ||
root: T; | ||
bottom: T; | ||
peek(): T; | ||
top: T; | ||
} | ||
} |
430
index.js
@@ -1,149 +0,299 @@ | ||
var adts; | ||
(function (adts) { | ||
var Bag = (function () { | ||
function Bag(elements) { | ||
if (elements === void 0) { elements = []; } | ||
this._element_object = {}; | ||
for (var i = 0, element; (element = elements[i]); i++) { | ||
this._element_object[element] = 1; | ||
} | ||
/** | ||
Bag: a multiset; i.e., a Set with counts. The underlying datatype | ||
is a object, `._element_object`. The effective default of members | ||
of `._element_object` is 0. Being undefined, having a value of undefined, | ||
null, false, etc., is all equivalent to having a 0 count. | ||
`Bag()` and `new Bag()` both return an empty bag. | ||
*/ | ||
var Bag = (function () { | ||
function Bag(elements) { | ||
if (elements === void 0) { elements = []; } | ||
this._element_object = {}; | ||
for (var i = 0, element; (element = elements[i]); i++) { | ||
this._element_object[element] = 1; | ||
} | ||
return Bag; | ||
})(); | ||
adts.Bag = Bag; | ||
})(adts || (adts = {})); | ||
var adts; | ||
(function (adts) { | ||
var Set = (function () { | ||
function Set(elements) { | ||
if (elements === void 0) { elements = []; } | ||
this._element_object = {}; | ||
for (var i = 0, element; (element = elements[i]); i++) { | ||
this._element_object[element] = true; | ||
} | ||
} | ||
return Bag; | ||
})(); | ||
exports.Bag = Bag; | ||
/** Compare two objects and return false as soon as we find a property | ||
* not present in both. Otherwise return true. */ | ||
function keysEqual(a, b) { | ||
for (var b_element in b) { | ||
if (!(b_element in a)) { | ||
return false; | ||
} | ||
// handle overloading constructor without `new` keyword | ||
//(elements: Array<string>): Set { | ||
// return new Set(elements); | ||
//} | ||
//if (!(this instanceof Set)) { | ||
// return new Set(elements); | ||
//} | ||
//if (elements instanceof Set) { | ||
// // creating a new S from another S will create a copy | ||
// elements = elements.toArray(); | ||
//} | ||
Set.prototype._add = function (element) { | ||
/** Mutable. */ | ||
} | ||
for (var a_element in a) { | ||
if (!(a_element in b)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
/** new Set(elements?: string[]) | ||
Set is an abstract data type supporting methods like .add(), .merge(), | ||
.contains(), and .equals(). It is implemented by an object with keys that | ||
represent elements in the set. The values of the object are all boolean true's; | ||
the value does not matter, only their presence does. | ||
All elements are coerced to strings by object index notation. | ||
*/ | ||
var Set = (function () { | ||
/** Create a new Set, optionally initializing it with an Array of strings */ | ||
function Set(elements) { | ||
this._element_object = {}; | ||
this._addArray(elements); | ||
} | ||
/** Clone this set, returning the copy. | ||
* [immutable] */ | ||
Set.prototype.clone = function () { | ||
var copy = new Set([]); | ||
for (var element in this._element_object) { | ||
copy._element_object[element] = true; | ||
} | ||
return copy; | ||
}; | ||
/** Return an unordered Array of strings representing this Set. | ||
* [immutable] */ | ||
Set.prototype.toJSON = function () { | ||
return Object.keys(this._element_object); | ||
}; | ||
// | ||
// mutable methods | ||
// | ||
/** Add a single element to this set. | ||
* [mutable, chainable] */ | ||
Set.prototype._add = function (element) { | ||
this._element_object[element] = true; | ||
return this; | ||
}; | ||
/** Add multiple elements to this set. | ||
* [mutable, chainable] */ | ||
Set.prototype._addArray = function (elements) { | ||
for (var i = 0, element; (element = elements[i]) !== undefined; i++) { | ||
this._element_object[element] = true; | ||
}; | ||
Set.prototype.add = function (element) { | ||
/** Immutable. Returns a new set. */ | ||
var s = new Set([element]); | ||
s._merge(this); | ||
return s; | ||
}; | ||
Set.prototype._merge = function (other_set) { | ||
for (var element in other_set._element_object) { | ||
this._element_object[element] = true; | ||
} | ||
}; | ||
Set.prototype._remove = function (element) { | ||
/** Mutable. No-op if the element doesn't exist anyway. */ | ||
} | ||
return this; | ||
}; | ||
/** Add all elements from another Set. | ||
* [mutable, chainable] */ | ||
Set.prototype._addSet = function (other) { | ||
for (var element in other._element_object) { | ||
this._element_object[element] = true; | ||
} | ||
return this; | ||
}; | ||
/** Remove a single element from this set. No-op if the element doesn't exist. | ||
* [mutable, chainable] */ | ||
Set.prototype._remove = function (element) { | ||
delete this._element_object[element]; | ||
}; | ||
/** Remove multiple elements from this set. | ||
* [mutable, chainable] */ | ||
Set.prototype._removeArray = function (elements) { | ||
for (var i = 0, element; (element = elements[i]) !== undefined; i++) { | ||
delete this._element_object[element]; | ||
}; | ||
Set.prototype.equal = function (other_set) { | ||
for (var other_element in other_set._element_object) { | ||
if (!this._element_object[other_element]) { | ||
return false; | ||
} | ||
} | ||
return this; | ||
}; | ||
/** Remove all elements from another Set. | ||
* [mutable, chainable] */ | ||
Set.prototype._removeSet = function (other) { | ||
for (var element in other._element_object) { | ||
delete this._element_object[element]; | ||
} | ||
return this; | ||
}; | ||
// | ||
// immutable methods | ||
// | ||
/** Return a new Set representing the union of this set and the given | ||
* element. | ||
* [immutable, chainable] */ | ||
Set.prototype.add = function (element) { | ||
return this.clone()._add(element); | ||
}; | ||
/** Return a new Set representing the union of this set and the given | ||
* elements. | ||
* [immutable, chainable] */ | ||
Set.prototype.addArray = function (elements) { | ||
return this.clone()._addArray(elements); | ||
}; | ||
/** Return a new Set representing the union of this set and another set. | ||
* [immutable, chainable] */ | ||
Set.prototype.addSet = function (other) { | ||
return this.clone()._addSet(other); | ||
}; | ||
/** Return a new Set representing the subtraction of the given element from | ||
* this Set. | ||
* [immutable, chainable] */ | ||
Set.prototype.remove = function (element) { | ||
return this.clone()._remove(element); | ||
}; | ||
/** Return a new Set representing the subtraction of the given elements from | ||
* this Set. | ||
* [immutable, chainable] */ | ||
Set.prototype.removeArray = function (elements) { | ||
return this.clone()._removeArray(elements); | ||
}; | ||
/** Return a new Set representing the subtraction of the given Set from | ||
* this Set. | ||
* [immutable, chainable] */ | ||
Set.prototype.removeSet = function (other) { | ||
return this.clone()._removeSet(other); | ||
}; | ||
// | ||
// set analysis | ||
// | ||
/** Pairwise set comparison. Return false at the first mismatch, otherwise | ||
* return true. | ||
* | ||
* new Set([1, 4, 9]).equal(new Set([9, 4, 1])) == true | ||
* new Set(['a', 'b', 'z']).equal(new Set(['a', 'b'])) == false | ||
* [immutable] */ | ||
Set.prototype.equals = function (other) { | ||
return keysEqual(this._element_object, other._element_object); | ||
}; | ||
/** Check if the given element is contained in this set. */ | ||
Set.prototype.contains = function (element) { | ||
return element in this._element_object; | ||
}; | ||
Object.defineProperty(Set.prototype, "size", { | ||
/** Simply . */ | ||
get: function () { | ||
// TODO: use an actual property and update it whenever mutating the | ||
// underlying _element_object | ||
var count = 0; | ||
for (var element in this._element_object) { | ||
count++; | ||
} | ||
for (var this_element in this._element_object) { | ||
if (!other_set._element_object[this_element]) { | ||
return false; | ||
} | ||
return count; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
// | ||
// static set operations | ||
// | ||
/** Compare an Array of Sets, returning true if they're all equal. | ||
*/ | ||
Set.equal = function (sets) { | ||
if (sets.length == 0) | ||
return undefined; // undefined | ||
if (sets.length == 1) | ||
return true; // trivially true | ||
// return on the first mismatch | ||
var prototype_set = sets[0]; | ||
for (var i = 1, other; (other = sets[i]) !== undefined; i++) { | ||
var prototype_other_equal = keysEqual(prototype_set._element_object, other._element_object); | ||
if (!prototype_other_equal) { | ||
return false; | ||
} | ||
return false; | ||
}; | ||
Set.prototype.contains = function (element) { | ||
return element in this._element_object; | ||
}; | ||
Set.prototype.toArray = function () { | ||
/** returns Array (of strings, usually) */ | ||
return Object.keys(this._element_object); | ||
}; | ||
//static intersect(sets: Array<Set>) { | ||
// var s = new Set(); | ||
// sets.forEach(function(set) { | ||
// s._merge(set); | ||
// }); | ||
// return s; | ||
//} | ||
//static subtract(sets) { | ||
//} | ||
Set.union = function (sets) { | ||
/** Immutable. Returns a new set that contains all the elements from the | ||
given sets (may be the empty set). */ | ||
var s = new Set(); | ||
// sets.forEach(s._merge.bind(s)); | ||
sets.forEach(function (set) { | ||
s._merge(set); | ||
}); | ||
return s; | ||
}; | ||
Set.equal = function (sets) { | ||
/** Compare an Array of sets, return true if they're all equal. | ||
*/ | ||
if (sets.length < 2) | ||
return true; | ||
// much like the instance.equal version, return on the first mismatch | ||
var prototype_set = sets[0]; | ||
for (var i = 1, other_set; (other_set = sets[i]); i++) { | ||
if (!prototype_set.equal(other_set)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
/** Return true if all the given Sets contain the given element. | ||
* Returns false on the first mismatch. */ | ||
Set.contain = function (sets, element) { | ||
for (var i = 0, set; (set = sets[i]) !== undefined; i++) { | ||
if (!(element in set._element_object)) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
return Set; | ||
})(); | ||
adts.Set = Set; | ||
})(adts || (adts = {})); | ||
var adts; | ||
(function (adts) { | ||
var Stack = (function () { | ||
function Stack() { | ||
this._array = []; | ||
} | ||
Object.defineProperty(Stack.prototype, "length", { | ||
get: function () { | ||
return this._array.length; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
return true; | ||
}; | ||
/** Return a new Set that contains all the elements from the given Sets. | ||
* [immutable] */ | ||
Set.union = function (sets) { | ||
if (sets.length == 0) | ||
return undefined; // undefined | ||
if (sets.length == 1) | ||
return sets[0].clone(); // trivial | ||
var union_set = new Set([]); | ||
for (var i = 0, set; (set = sets[i]) !== undefined; i++) { | ||
union_set._addSet(set); | ||
} | ||
return union_set; | ||
}; | ||
/** Return a new Set representing the intersection of all given Sets. | ||
* [immutable] */ | ||
Set.intersection = function (sets) { | ||
if (sets.length == 0) | ||
return undefined; // undefined | ||
if (sets.length == 1) | ||
return sets[0].clone(); // trivial | ||
// reorder sets from smallest to largest | ||
sets = sets.sort(function (a, b) { | ||
return a.size - b.size; | ||
}); | ||
Stack.prototype.push = function (item) { | ||
this._array.push(item); | ||
}; | ||
Stack.prototype.pop = function () { | ||
return this._array.pop(); | ||
}; | ||
Object.defineProperty(Stack.prototype, "root", { | ||
get: function () { | ||
return this._array[0]; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Object.defineProperty(Stack.prototype, "top", { | ||
get: function () { | ||
return this._array[this._array.length - 1]; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
return Stack; | ||
})(); | ||
adts.Stack = Stack; | ||
})(adts || (adts = {})); | ||
module.exports = adts; | ||
var prototype_set = sets[0]; | ||
var other_sets = sets.slice(1); | ||
var intersection_set = new Set([]); | ||
for (var element in prototype_set._element_object) { | ||
var other_sets_contain_element = Set.contain(other_sets, element); | ||
if (other_sets_contain_element) { | ||
intersection_set._element_object[element] = true; | ||
} | ||
} | ||
return intersection_set; | ||
}; | ||
return Set; | ||
})(); | ||
exports.Set = Set; | ||
/** new Stack<T>(elements?: T[]) | ||
Basically a simplified Array wrapper, with Stack#bottom and Stack#top getters. | ||
When initialized with an Array, the last element in the array will be the top of | ||
the Stack. The constructor's elements argment is optional, and defaults to an | ||
empty array. | ||
*/ | ||
var Stack = (function () { | ||
function Stack(elements) { | ||
if (elements === void 0) { elements = []; } | ||
this._array = elements; | ||
} | ||
Object.defineProperty(Stack.prototype, "length", { | ||
/** Stack#length | ||
Returns size of stack. | ||
*/ | ||
get: function () { | ||
return this._array.length; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
/** Stack#push(element) | ||
Returns size of stack after adding element. | ||
*/ | ||
Stack.prototype.push = function (element) { | ||
return this._array.push(element); | ||
}; | ||
Stack.prototype.pop = function () { | ||
return this._array.pop(); | ||
}; | ||
Object.defineProperty(Stack.prototype, "bottom", { | ||
get: function () { | ||
return this._array[0]; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Stack.prototype.peek = function () { | ||
return this._array[this._array.length - 1]; | ||
}; | ||
Object.defineProperty(Stack.prototype, "top", { | ||
get: function () { | ||
return this._array[this._array.length - 1]; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
return Stack; | ||
})(); | ||
exports.Stack = Stack; |
{ | ||
"name": "adts", | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"description": "Abstract Data Types in TypeScript", | ||
@@ -23,2 +23,6 @@ "keywords": [ | ||
"author": "Christopher Brown <io@henrian.com> (http://henrian.com)", | ||
"devDependencies": { | ||
"TypeScript": "*", | ||
"mocha": "*" | ||
}, | ||
"scripts": { | ||
@@ -25,0 +29,0 @@ "prepublish": "make" |
@@ -13,2 +13,8 @@ # adts | ||
## Example import | ||
/// <reference path="../node_modules/adts/adts.d.ts"/> | ||
import adts = require('adts'); | ||
## TODO | ||
@@ -35,2 +41,2 @@ | ||
Copyright ©2014 Christopher Brown. MIT Licensed. | ||
Copyright 2014-2015 Christopher Brown. [MIT Licensed](http://opensource.org/licenses/MIT). |
@@ -1,48 +0,41 @@ | ||
module adts { | ||
export class Bag { | ||
/** | ||
Bag: a multiset; i.e., a Set with counts. The underlying datatype | ||
is a object, `._element_object`. The effective default of members | ||
of `._element_object` is 0. Being undefined, having a value of undefined, | ||
null, false, etc., is all equivalent to having a 0 count. | ||
/** | ||
Bag: a multiset; i.e., a Set with counts. The underlying datatype | ||
is a object, `._element_object`. The effective default of members | ||
of `._element_object` is 0. Being undefined, having a value of undefined, | ||
null, false, etc., is all equivalent to having a 0 count. | ||
`Bag()` and `new Bag()` both return an empty bag. | ||
*/ | ||
// handle overloading constructor without `new` keyword | ||
//if (!(this instanceof Bag)) { | ||
// return new Bag(counts); | ||
//} | ||
//if (counts instanceof Bag) { | ||
// return counts.clone(); | ||
//} | ||
//else if (elements instanceof Set) { | ||
// // creating a new S from another S will create a copy | ||
// elements = elements.toArray(); | ||
//} | ||
private _element_object: {[index: string]: number}; | ||
constructor(elements: Array<string> = []) { | ||
this._element_object = {}; | ||
for (var i = 0, element; (element = elements[i]); i++) { | ||
this._element_object[element] = 1; | ||
} | ||
`Bag()` and `new Bag()` both return an empty bag. | ||
*/ | ||
export class Bag { | ||
//if (counts instanceof Bag) { | ||
// return counts.clone(); | ||
//} | ||
//else if (elements instanceof Set) { | ||
// // creating a new S from another S will create a copy | ||
// elements = elements.toArray(); | ||
//} | ||
private _element_object: {[index: string]: number}; | ||
constructor(elements: Array<string> = []) { | ||
this._element_object = {}; | ||
for (var i = 0, element; (element = elements[i]); i++) { | ||
this._element_object[element] = 1; | ||
} | ||
} | ||
//countOf(element) { | ||
// /** | ||
// * Return the number of times `element` shows up in this Bag, a.k.a., the | ||
// * multiplicity of `element` */ | ||
// //return this._element_object[element]; | ||
//} | ||
//_add(elements) { | ||
// /** */ | ||
// //return this._element_object[element]; | ||
//} | ||
// | ||
//static fromSet(element) { | ||
// /** Return the number of times `element` shows up in this Bag, a.k.a., the | ||
// multiplicity of `element` */ | ||
// //return this._element_object[element]; | ||
//} | ||
} | ||
//countOf(element) { | ||
// /** | ||
// * Return the number of times `element` shows up in this Bag, a.k.a., the | ||
// * multiplicity of `element` */ | ||
// //return this._element_object[element]; | ||
//} | ||
//_add(elements) { | ||
// /** */ | ||
// //return this._element_object[element]; | ||
//} | ||
// | ||
//static fromSet(element) { | ||
// /** Return the number of times `element` shows up in this Bag, a.k.a., the | ||
// multiplicity of `element` */ | ||
// //return this._element_object[element]; | ||
//} | ||
} |
300
src/set.ts
@@ -1,111 +0,229 @@ | ||
module adts { | ||
export class Set { | ||
/** | ||
S = Set: a helper around an object with keys that represent elements in the set. | ||
The values of the object are all true; they do not really matter. | ||
This object is available at the private member `._element_object`. | ||
/** Compare two objects and return false as soon as we find a property | ||
* not present in both. Otherwise return true. */ | ||
function keysEqual(a: {[index: string]: any}, b: {[index: string]: any}) { | ||
for (var b_element in b) { | ||
if (!(b_element in a)) { | ||
return false; | ||
} | ||
} | ||
for (var a_element in a) { | ||
if (!(a_element in b)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
S(), S([]), new S(), and new S([]) will all return the empty set. | ||
/** new Set(elements?: string[]) | ||
*/ | ||
private _element_object: {[index: string]: boolean}; | ||
constructor(elements: Array<string> = []) { | ||
this._element_object = {}; | ||
for (var i = 0, element; (element = elements[i]); i++) { | ||
this._element_object[element] = true; | ||
} | ||
Set is an abstract data type supporting methods like .add(), .merge(), | ||
.contains(), and .equals(). It is implemented by an object with keys that | ||
represent elements in the set. The values of the object are all boolean true's; | ||
the value does not matter, only their presence does. | ||
All elements are coerced to strings by object index notation. | ||
*/ | ||
export class Set { | ||
private _element_object: {[index: string]: boolean}; | ||
/** Create a new Set, optionally initializing it with an Array of strings */ | ||
constructor(elements?: string[]) { | ||
this._element_object = {}; | ||
this._addArray(elements); | ||
} | ||
/** Clone this set, returning the copy. | ||
* [immutable] */ | ||
clone() { | ||
var copy = new Set([]); | ||
for (var element in this._element_object) { | ||
copy._element_object[element] = true; | ||
} | ||
// handle overloading constructor without `new` keyword | ||
//(elements: Array<string>): Set { | ||
// return new Set(elements); | ||
//} | ||
//if (!(this instanceof Set)) { | ||
// return new Set(elements); | ||
//} | ||
//if (elements instanceof Set) { | ||
// // creating a new S from another S will create a copy | ||
// elements = elements.toArray(); | ||
//} | ||
_add(element: string) { | ||
/** Mutable. */ | ||
return copy; | ||
} | ||
/** Return an unordered Array of strings representing this Set. | ||
* [immutable] */ | ||
toJSON() { | ||
return Object.keys(this._element_object); | ||
} | ||
// | ||
// mutable methods | ||
// | ||
/** Add a single element to this set. | ||
* [mutable, chainable] */ | ||
_add(element: string) { | ||
this._element_object[element] = true; | ||
return this; | ||
} | ||
/** Add multiple elements to this set. | ||
* [mutable, chainable] */ | ||
_addArray(elements: string[]) { | ||
for (var i = 0, element; (element = elements[i]) !== undefined; i++) { | ||
this._element_object[element] = true; | ||
} | ||
add(element: string) { | ||
/** Immutable. Returns a new set. */ | ||
var s = new Set([element]); | ||
s._merge(this); | ||
return s; | ||
return this; | ||
} | ||
/** Add all elements from another Set. | ||
* [mutable, chainable] */ | ||
_addSet(other: Set) { | ||
for (var element in other._element_object) { | ||
this._element_object[element] = true; | ||
} | ||
_merge(other_set: Set) { | ||
/** Mutable. */ | ||
for (var element in other_set._element_object) { | ||
this._element_object[element] = true; | ||
} | ||
return this; | ||
} | ||
/** Remove a single element from this set. No-op if the element doesn't exist. | ||
* [mutable, chainable] */ | ||
_remove(element: string) { | ||
delete this._element_object[element]; | ||
} | ||
/** Remove multiple elements from this set. | ||
* [mutable, chainable] */ | ||
_removeArray(elements: string) { | ||
for (var i = 0, element; (element = elements[i]) !== undefined; i++) { | ||
delete this._element_object[element]; | ||
} | ||
_remove(element: string) { | ||
/** Mutable. No-op if the element doesn't exist anyway. */ | ||
return this; | ||
} | ||
/** Remove all elements from another Set. | ||
* [mutable, chainable] */ | ||
_removeSet(other: Set) { | ||
for (var element in other._element_object) { | ||
delete this._element_object[element]; | ||
} | ||
equal(other_set: Set) { | ||
/** Pairwise set comparison. Return false at the first mismatch. | ||
return this; | ||
} | ||
S([1, 4, 9]).equal(S([9, 4, 1])) == true | ||
S(['a', 'b', 'z']).equal(S(['a', 'b'])) == false | ||
// | ||
// immutable methods | ||
// | ||
TODO: avoid overlapping comparisons? | ||
*/ | ||
for (var other_element in other_set._element_object) { | ||
if (!this._element_object[other_element]) { | ||
return false; | ||
} | ||
/** Return a new Set representing the union of this set and the given | ||
* element. | ||
* [immutable, chainable] */ | ||
add(element: string) { | ||
return this.clone()._add(element); | ||
} | ||
/** Return a new Set representing the union of this set and the given | ||
* elements. | ||
* [immutable, chainable] */ | ||
addArray(elements: string[]) { | ||
return this.clone()._addArray(elements); | ||
} | ||
/** Return a new Set representing the union of this set and another set. | ||
* [immutable, chainable] */ | ||
addSet(other: Set) { | ||
return this.clone()._addSet(other); | ||
} | ||
/** Return a new Set representing the subtraction of the given element from | ||
* this Set. | ||
* [immutable, chainable] */ | ||
remove(element: string) { | ||
return this.clone()._remove(element); | ||
} | ||
/** Return a new Set representing the subtraction of the given elements from | ||
* this Set. | ||
* [immutable, chainable] */ | ||
removeArray(elements: string) { | ||
return this.clone()._removeArray(elements); | ||
} | ||
/** Return a new Set representing the subtraction of the given Set from | ||
* this Set. | ||
* [immutable, chainable] */ | ||
removeSet(other: Set) { | ||
return this.clone()._removeSet(other); | ||
} | ||
// | ||
// set analysis | ||
// | ||
/** Pairwise set comparison. Return false at the first mismatch, otherwise | ||
* return true. | ||
* | ||
* new Set([1, 4, 9]).equal(new Set([9, 4, 1])) == true | ||
* new Set(['a', 'b', 'z']).equal(new Set(['a', 'b'])) == false | ||
* [immutable] */ | ||
equals(other: Set) { | ||
return keysEqual(this._element_object, other._element_object); | ||
} | ||
/** Check if the given element is contained in this set. */ | ||
contains(element: string) { | ||
return element in this._element_object; | ||
} | ||
/** Simply . */ | ||
get size() { | ||
// TODO: use an actual property and update it whenever mutating the | ||
// underlying _element_object | ||
var count = 0; | ||
for (var element in this._element_object) { | ||
count++; | ||
} | ||
return count; | ||
} | ||
// | ||
// static set operations | ||
// | ||
/** Compare an Array of Sets, returning true if they're all equal. | ||
*/ | ||
static equal(sets: Set[]) { | ||
if (sets.length == 0) return undefined; // undefined | ||
if (sets.length == 1) return true; // trivially true | ||
// return on the first mismatch | ||
var prototype_set = sets[0]; | ||
// use a for loop to allow immediate return | ||
for (var i = 1, other; (other = sets[i]) !== undefined; i++) { | ||
var prototype_other_equal = keysEqual(prototype_set._element_object, other._element_object); | ||
if (!prototype_other_equal) { | ||
return false; | ||
} | ||
for (var this_element in this._element_object) { | ||
if (!other_set._element_object[this_element]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
/** Return true if all the given Sets contain the given element. | ||
* Returns false on the first mismatch. */ | ||
static contain(sets: Set[], element: string) { | ||
for (var i = 0, set; (set = sets[i]) !== undefined; i++) { | ||
if (!(element in set._element_object)) { | ||
return false; | ||
} | ||
return false; | ||
} | ||
contains(element) { | ||
return element in this._element_object; | ||
return true; | ||
} | ||
/** Return a new Set that contains all the elements from the given Sets. | ||
* [immutable] */ | ||
static union(sets: Set[]) { | ||
if (sets.length == 0) return undefined; // undefined | ||
if (sets.length == 1) return sets[0].clone(); // trivial | ||
var union_set = new Set([]); | ||
for (var i = 0, set; (set = sets[i]) !== undefined; i++) { | ||
union_set._addSet(set); | ||
} | ||
toArray() { | ||
/** returns Array (of strings, usually) */ | ||
return Object.keys(this._element_object); | ||
} | ||
return union_set; | ||
} | ||
//static intersect(sets: Array<Set>) { | ||
// var s = new Set(); | ||
// sets.forEach(function(set) { | ||
// s._merge(set); | ||
// }); | ||
// return s; | ||
//} | ||
//static subtract(sets) { | ||
//} | ||
static union(sets: Array<Set>) { | ||
/** Immutable. Returns a new set that contains all the elements from the | ||
given sets (may be the empty set). */ | ||
var s = new Set(); | ||
// sets.forEach(s._merge.bind(s)); | ||
sets.forEach(function(set) { | ||
s._merge(set); | ||
}); | ||
return s; | ||
} | ||
static equal(sets: Array<Set>) { | ||
/** Compare an Array of sets, return true if they're all equal. | ||
*/ | ||
if (sets.length < 2) return true; | ||
// much like the instance.equal version, return on the first mismatch | ||
var prototype_set = sets[0]; | ||
// use a for loop to allow immediate return | ||
for (var i = 1, other_set; (other_set = sets[i]); i++) { | ||
if (!prototype_set.equal(other_set)) { | ||
return false; | ||
} | ||
/** Return a new Set representing the intersection of all given Sets. | ||
* [immutable] */ | ||
static intersection(sets: Set[]) { | ||
if (sets.length == 0) return undefined; // undefined | ||
if (sets.length == 1) return sets[0].clone(); // trivial | ||
// reorder sets from smallest to largest | ||
sets = sets.sort(function(a, b) { | ||
return a.size - b.size; | ||
}); | ||
var prototype_set = sets[0]; | ||
var other_sets = sets.slice(1); | ||
var intersection_set = new Set([]); | ||
for (var element in prototype_set._element_object) { | ||
var other_sets_contain_element = Set.contain(other_sets, element); | ||
if (other_sets_contain_element) { | ||
intersection_set._element_object[element] = true; | ||
} | ||
return true; | ||
} | ||
return intersection_set; | ||
} | ||
} |
@@ -1,25 +0,40 @@ | ||
module adts { | ||
export class Stack<T> { | ||
/** Stack is mostly an impoverished Array wrapper, | ||
but with a .top helper */ | ||
private _array: Array<T>; | ||
constructor() { | ||
this._array = []; | ||
} | ||
get length(): number { | ||
return this._array.length; | ||
} | ||
push(item: T): void { | ||
this._array.push(item); | ||
} | ||
pop(): T { | ||
return this._array.pop(); | ||
} | ||
get root(): T { | ||
return this._array[0]; | ||
} | ||
get top(): T { | ||
return this._array[this._array.length - 1]; | ||
} | ||
/** new Stack<T>(elements?: T[]) | ||
Basically a simplified Array wrapper, with Stack#bottom and Stack#top getters. | ||
When initialized with an Array, the last element in the array will be the top of | ||
the Stack. The constructor's elements argment is optional, and defaults to an | ||
empty array. | ||
*/ | ||
export class Stack<T> { | ||
private _array: T[]; | ||
constructor(elements: T[] = []) { | ||
this._array = elements; | ||
} | ||
/** Stack#length | ||
Returns size of stack. | ||
*/ | ||
get length(): number { | ||
return this._array.length; | ||
} | ||
/** Stack#push(element) | ||
Returns size of stack after adding element. | ||
*/ | ||
push(element: T): number { | ||
return this._array.push(element); | ||
} | ||
pop(): T { | ||
return this._array.pop(); | ||
} | ||
get bottom(): T { | ||
return this._array[0]; | ||
} | ||
peek(): T { | ||
return this._array[this._array.length - 1]; | ||
} | ||
get top(): T { | ||
return this._array[this._array.length - 1]; | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
51429
22
768
41
2
1