tsbase
Version:
Base class libraries for TypeScript
239 lines • 9.93 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Queryable = void 0;
var tslib_1 = require("tslib");
/* eslint-disable max-lines */
var Regex_1 = require("../../System/Regex");
var Strings_1 = require("../../System/Strings");
var module_1 = require("../../Utility/Logger/module");
var Queryable = /** @class */ (function (_super) {
tslib_1.__extends(Queryable, _super);
function Queryable() {
return _super.call(this) || this;
}
Queryable.From = function (items) {
return Object.create(Queryable.prototype, Object.getOwnPropertyDescriptors(items));
};
/**
* Returns a copy of the array shuffled based on the knuth shuffle algorithm
*/
Queryable.prototype.Shuffle = function () {
return this.mutableArrayQuery(function (array) {
var currentIndex = array.length, temporaryValue, randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return Queryable.From(array);
});
};
/**
* Returns all elements except for the set specified.
* @param items
*/
Queryable.prototype.Except = function (items) {
return this.mutableArrayQuery(function (array) {
var stringifiedItemsToExclude = JSON.stringify(items);
array = array.filter(function (item) { return stringifiedItemsToExclude.indexOf(JSON.stringify(item)) < 0; });
return Queryable.From(array);
});
};
/**
* Returns a random item from the array based on Knuth shuffle
* @param excluding - optionally exclude an array of items when selecting a random element
*/
Queryable.prototype.GetRandom = function (excluding) {
var candidateElements = excluding ? this.Except(excluding) : this;
var shuffledItems = candidateElements.Shuffle();
return shuffledItems.length >= 1 ? shuffledItems[0] : null;
};
/**
* Sorts the elements of a sequence in ascending order based on the default comparer or user defined function(s)
* @param funcs
*/
Queryable.prototype.OrderBy = function (funcs) {
return this.mutableArrayQuery(function (array) {
if (!funcs) {
array.sort();
}
else {
array.sort(function (a, b) {
var result = 0;
for (var index = 0; index < funcs.length; index++) {
var func = funcs[index];
if (func(a) < func(b)) {
result = -1;
break;
}
else if (func(a) > func(b)) {
result = 1;
break;
}
}
return result;
});
}
return Queryable.From(array);
});
};
/**
* Sorts the elements of a sequence in descending order.
* @param func
*/
Queryable.prototype.OrderByDescending = function (funcs) {
return Queryable.From(this.OrderBy(funcs).reverse());
};
/**
* Returns the first element of a sequence or null if the sequence is empty.
* @param func optionally retrieve the first element which satisfies the given predicate
*/
Queryable.prototype.First = function (func) {
if (func) {
return this.find(func) || null;
}
else {
var firstElement = this.length >= 1 ? this[0] : null;
return firstElement;
}
};
/**
* Returns the last element of a sequence or null if the sequence is empty.
* @param func optionally retrieve the last element which satisfies the given predicate
*/
Queryable.prototype.Last = function (func) {
if (func) {
return this.slice().reverse().find(func) || null;
}
else {
var lastElement = this.length >= 1 ? this[this.length - 1] : null;
return lastElement;
}
};
/**
* Returns the element with the minimum value in a sequence of values.
* @param func
*/
Queryable.prototype.Min = function (func) {
if (func === void 0) { func = function (item) { return item; }; }
return this.length < 1 ?
null :
this.reduce(function (current, next) { return func(current) < func(next) ? current : next; }, this[0]);
};
/**
* Returns the element with the maximum value in a sequence of values.
* @param func
*/
Queryable.prototype.Max = function (func) {
if (func === void 0) { func = function (item) { return item; }; }
return this.length < 1 ?
null :
this.reduce(function (current, next) { return func(current) > func(next) ? current : next; }, this[0]);
};
/**
* Computes the sum of a sequence of numeric values, or the sum result of the given function
* @param func
*/
Queryable.prototype.Sum = function (func) {
try {
var sum_1 = 0;
if (func) {
this.forEach(function (element) {
sum_1 += func(element);
});
}
else {
this.forEach(function (element) {
var tNumber = parseFloat(element.toString());
if (isNaN(tNumber)) {
throw new Error("Sum failed - \"".concat(tNumber, "\" is not a number."));
}
sum_1 += tNumber;
});
}
return sum_1;
}
catch (error) {
module_1.Logger.Instance.Log(new module_1.LogEntry(error.message, module_1.LogLevel.Error, error));
return null;
}
};
/**
* Computes the average of a sequence of numeric values, or the average result of the given function
* @param func
*/
Queryable.prototype.Average = function (func) {
var sum = func ? this.Sum(func) : this.Sum();
return this.length > 0 && sum ?
sum / this.length :
null;
};
/**
* Returns distinct elements from a sequence.
* @param func
*/
Queryable.prototype.Distinct = function () {
var itemsToReturn = [];
for (var index = 0; index < this.length; index++) {
var element = this[index];
var stringifiedItems = JSON.stringify(itemsToReturn);
if (stringifiedItems.indexOf(JSON.stringify(element)) === -1) {
itemsToReturn.push(element);
}
}
return Queryable.From(itemsToReturn);
};
/**
* Perform a full text search on a collection for a given search term. Elements containing the entire search term
* are given precedence over keyword matches.
* @param term The term being searched for
* @param minimumKeywordLength Keywords in the search term with a length less than this won't be considered
* @param stopWords Keywords matching these words are not considered
* @param ignorableSuffixCharacters Characters that should not prevent a positive match
* (i.e. allows toy's' to match on toy)
*/
Queryable.prototype.Search = function (term, minimumKeywordLength, stopWords, ignorableSuffixCharacters) {
if (minimumKeywordLength === void 0) { minimumKeywordLength = 3; }
if (stopWords === void 0) { stopWords = new Array(); }
if (ignorableSuffixCharacters === void 0) { ignorableSuffixCharacters = new Array(); }
var keywords = this.getKeywordsForTerm(term, ignorableSuffixCharacters);
stopWords = stopWords.map(function (s) { return s.toLowerCase(); });
var exactMatches = this.filter(function (item) { return JSON.stringify(item).toLowerCase().indexOf(term.toLowerCase()) >= 0; }).slice();
var keywordMatches = this.getKeywordMatches(keywords, minimumKeywordLength, stopWords);
var distinctResults = Queryable.From(exactMatches.concat(keywordMatches)).Distinct();
return distinctResults;
};
Queryable.prototype.getKeywordsForTerm = function (term, ignorableSuffixCharacters) {
var keywords = term.split(Strings_1.Strings.Space);
keywords.forEach(function (element) {
element = element.replace(Regex_1.Regex.NonAlphaNumeric, Strings_1.Strings.Empty);
var lastCharacter = element[element.length - 1];
if (ignorableSuffixCharacters && ignorableSuffixCharacters.indexOf(lastCharacter) >= 0) {
keywords.push(element.split(lastCharacter)[0]);
}
});
return keywords;
};
Queryable.prototype.getKeywordMatches = function (keywords, minimumKeywordLength, stopWords) {
var _this = this;
var keywordMatches = new Array();
if (keywords.length > 0) {
keywords.forEach(function (keyword) {
if (keyword.length >= minimumKeywordLength &&
stopWords.indexOf(keyword.toLowerCase()) < 0) {
var keywordMatchesFound = _this.filter(function (item) { return JSON.stringify(item).toLowerCase().indexOf(keyword.toLowerCase()) >= 0; });
keywordMatches = keywordMatches.concat(keywordMatchesFound.slice());
}
});
}
return keywordMatches;
};
Queryable.prototype.mutableArrayQuery = function (func) {
return Queryable.From(func(this.slice()));
};
return Queryable;
}(Array));
exports.Queryable = Queryable;
//# sourceMappingURL=Queryable.js.map