typescript-collections
Version:
A complete, fully tested data structure library written in TypeScript.
185 lines • 6.42 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var util = require("./util");
var Dictionary_1 = require("./Dictionary");
var Set_1 = require("./Set");
var Bag = /** @class */ (function () {
/**
* Creates an empty bag.
* @class <p>A bag is a special kind of set in which members are
* allowed to appear more than once.</p>
* <p>If the inserted elements are custom objects a function
* which converts elements to unique strings must be provided. Example:</p>
*
* <pre>
* function petToString(pet) {
* return pet.name;
* }
* </pre>
*
* @constructor
* @param {function(Object):string=} toStrFunction optional function used
* to convert elements to strings. If the elements aren't strings or if toString()
* is not appropriate, a custom function which receives an object and returns a
* unique string must be provided.
*/
function Bag(toStrFunction) {
this.toStrF = toStrFunction || util.defaultToString;
this.dictionary = new Dictionary_1.default(this.toStrF);
this.nElements = 0;
}
/**
* Adds nCopies of the specified object to this bag.
* @param {Object} element element to add.
* @param {number=} nCopies the number of copies to add, if this argument is
* undefined 1 copy is added.
* @return {boolean} true unless element is undefined.
*/
Bag.prototype.add = function (element, nCopies) {
if (nCopies === void 0) { nCopies = 1; }
if (util.isUndefined(element) || nCopies <= 0) {
return false;
}
if (!this.contains(element)) {
var node = {
value: element,
copies: nCopies
};
this.dictionary.setValue(element, node);
}
else {
this.dictionary.getValue(element).copies += nCopies;
}
this.nElements += nCopies;
return true;
};
/**
* Counts the number of copies of the specified object in this bag.
* @param {Object} element the object to search for..
* @return {number} the number of copies of the object, 0 if not found
*/
Bag.prototype.count = function (element) {
if (!this.contains(element)) {
return 0;
}
else {
return this.dictionary.getValue(element).copies;
}
};
/**
* Returns true if this bag contains the specified element.
* @param {Object} element element to search for.
* @return {boolean} true if this bag contains the specified element,
* false otherwise.
*/
Bag.prototype.contains = function (element) {
return this.dictionary.containsKey(element);
};
/**
* Removes nCopies of the specified object to this bag.
* If the number of copies to remove is greater than the actual number
* of copies in the Bag, all copies are removed.
* @param {Object} element element to remove.
* @param {number=} nCopies the number of copies to remove, if this argument is
* undefined 1 copy is removed.
* @return {boolean} true if at least 1 element was removed.
*/
Bag.prototype.remove = function (element, nCopies) {
if (nCopies === void 0) { nCopies = 1; }
if (util.isUndefined(element) || nCopies <= 0) {
return false;
}
if (!this.contains(element)) {
return false;
}
else {
var node = this.dictionary.getValue(element);
if (nCopies > node.copies) {
this.nElements -= node.copies;
}
else {
this.nElements -= nCopies;
}
node.copies -= nCopies;
if (node.copies <= 0) {
this.dictionary.remove(element);
}
return true;
}
};
/**
* Returns an array containing all of the elements in this big in arbitrary order,
* including multiple copies.
* @return {Array} an array containing all of the elements in this bag.
*/
Bag.prototype.toArray = function () {
var a = [];
var values = this.dictionary.values();
for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
var node = values_1[_i];
var element = node.value;
var copies = node.copies;
for (var j = 0; j < copies; j++) {
a.push(element);
}
}
return a;
};
/**
* Returns a set of unique elements in this bag.
* @return {collections.Set<T>} a set of unique elements in this bag.
*/
Bag.prototype.toSet = function () {
var toret = new Set_1.default(this.toStrF);
var elements = this.dictionary.values();
for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
var ele = elements_1[_i];
var value = ele.value;
toret.add(value);
}
return toret;
};
/**
* Executes the provided function once for each element
* present in this bag, including multiple copies.
* @param {function(Object):*} callback function to execute, it is
* invoked with one argument: the element. To break the iteration you can
* optionally return false.
*/
Bag.prototype.forEach = function (callback) {
this.dictionary.forEach(function (k, v) {
var value = v.value;
var copies = v.copies;
for (var i = 0; i < copies; i++) {
if (callback(value) === false) {
return false;
}
}
return true;
});
};
/**
* Returns the number of elements in this bag.
* @return {number} the number of elements in this bag.
*/
Bag.prototype.size = function () {
return this.nElements;
};
/**
* Returns true if this bag contains no elements.
* @return {boolean} true if this bag contains no elements.
*/
Bag.prototype.isEmpty = function () {
return this.nElements === 0;
};
/**
* Removes all of the elements from this bag.
*/
Bag.prototype.clear = function () {
this.nElements = 0;
this.dictionary.clear();
};
return Bag;
}()); // End of bag
exports.default = Bag;
//# sourceMappingURL=Bag.js.map