UNPKG

linqts

Version:
733 lines 29.5 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; import { composeComparers, isObj, equal, keyComparer } from './helpers.js'; var List = /** @class */ (function () { /** * Defaults the elements of the list */ function List(elements) { if (elements === void 0) { elements = []; } this._elements = __spreadArray([], __read(elements), false); } /** * Make the List iterable and Spreadable */ List.prototype[Symbol.iterator] = function () { var _a, _b, element, e_1_1; var e_1, _c; return __generator(this, function (_d) { switch (_d.label) { case 0: _d.trys.push([0, 5, 6, 7]); _a = __values(this._elements), _b = _a.next(); _d.label = 1; case 1: if (!!_b.done) return [3 /*break*/, 4]; element = _b.value; return [4 /*yield*/, element]; case 2: _d.sent(); _d.label = 3; case 3: _b = _a.next(); return [3 /*break*/, 1]; case 4: return [3 /*break*/, 7]; case 5: e_1_1 = _d.sent(); e_1 = { error: e_1_1 }; return [3 /*break*/, 7]; case 6: try { if (_b && !_b.done && (_c = _a.return)) _c.call(_a); } finally { if (e_1) throw e_1.error; } return [7 /*endfinally*/]; case 7: return [2 /*return*/]; } }); }; Object.defineProperty(List.prototype, Symbol.toStringTag, { /** * property represents the Object name */ get: function () { return 'List'; // Expected output: "[object List]" }, enumerable: false, configurable: true }); /** * Adds an object to the end of the List<T>. */ List.prototype.Add = function (element) { this._elements.push(element); }; /** * Appends an object to the end of the List<T>. */ List.prototype.Append = function (element) { this.Add(element); }; /** * Add an object to the start of the List<T>. */ List.prototype.Prepend = function (element) { this._elements.unshift(element); }; /** * Adds the elements of the specified collection to the end of the List<T>. */ List.prototype.AddRange = function (elements) { var _a; (_a = this._elements).push.apply(_a, __spreadArray([], __read(elements), false)); }; /** * Applies an accumulator function over a sequence. */ List.prototype.Aggregate = function (accumulator, initialValue) { return this._elements.reduce(accumulator, initialValue); }; /** * Determines whether all elements of a sequence satisfy a condition. */ List.prototype.All = function (predicate) { return this._elements.every(predicate); }; /** * Determines whether a sequence contains any elements. */ List.prototype.Any = function (predicate) { return predicate ? this._elements.some(predicate) : this._elements.length > 0; }; /** * Computes the average of a sequence of number values that are obtained by invoking * a transform function on each element of the input sequence. */ List.prototype.Average = function (transform) { return this.Sum(transform) / this.Count(transform); }; /** * Casts the elements of a sequence to the specified type. */ List.prototype.Cast = function () { return new List(this._elements); }; /** * Removes all elements from the List<T>. */ List.prototype.Clear = function () { this._elements.length = 0; }; /** * Concatenates two sequences. */ List.prototype.Concat = function (list) { return new List(this._elements.concat(list.ToArray())); }; /** * Determines whether an element is in the List<T>. */ List.prototype.Contains = function (element) { return this.Any(function (x) { return x === element; }); }; /** * Returns the number of elements in a sequence. */ List.prototype.Count = function (predicate) { return predicate ? this.Where(predicate).Count() : this._elements.length; }; /** * Returns the elements of the specified sequence or the type parameter's default value * in a singleton collection if the sequence is empty. */ List.prototype.DefaultIfEmpty = function (defaultValue) { return this.Count() ? this : new List([defaultValue]); }; /** * Returns distinct elements from a sequence by using the default equality comparer to compare values. */ List.prototype.Distinct = function () { return this.Where(function (value, index, iter) { return (isObj(value) ? iter && iter.findIndex(function (obj) { return equal(obj, value); }) : iter && iter.indexOf(value)) === index; }); }; /** * Returns distinct elements from a sequence according to specified key selector. */ List.prototype.DistinctBy = function (keySelector) { var groups = this.GroupBy(keySelector); return Object.keys(groups).reduce(function (res, key) { var _a; var firstElement = (_a = groups === null || groups === void 0 ? void 0 : groups[key]) === null || _a === void 0 ? void 0 : _a[0]; if (firstElement !== undefined) { res.Add(firstElement); } return res; }, new List()); }; /** * Returns the element at a specified index in a sequence. */ List.prototype.ElementAt = function (index) { if (index < this.Count() && index >= 0) { return this._elements[index]; } throw new Error('ArgumentOutOfRangeException: index is less than 0 or greater than or equal to the number of elements in source.'); }; /** * Returns the element at a specified index in a sequence or a default value if the index is out of range. */ List.prototype.ElementAtOrDefault = function (index) { var _a; return index < this.Count() && index >= 0 ? (_a = this._elements[index]) !== null && _a !== void 0 ? _a : null : null; }; /** * Produces the set difference of two sequences by using the default equality comparer to compare values. */ List.prototype.Except = function (source) { return this.Where(function (x) { return !source.Contains(x); }); }; /** * Returns the first element of a sequence. */ List.prototype.First = function (predicate) { if (this.Count()) { return predicate ? this.Where(predicate).First() : this._elements[0]; } throw new Error('InvalidOperationException: The source sequence is empty.'); }; /** * Returns the first element of a sequence, or a default value if the sequence contains no elements. */ List.prototype.FirstOrDefault = function (defaultValue) { return this.Count() ? this.First() : defaultValue; }; /** * Performs the specified action on each element of the List<T>. */ List.prototype.ForEach = function (action) { return this._elements.forEach(action); }; /** * Groups the elements of a sequence according to a specified key selector function. */ List.prototype.GroupBy = function (grouper, mapper) { if (mapper === void 0) { mapper = function (val) { return val; }; } var initialValue = {}; return this.Aggregate(function (ac, v) { var key = grouper(v); var existingGroup = isObj(ac) && ac[key]; var mappedValue = mapper(v); if (!!existingGroup) { existingGroup.push(mappedValue); } else { ; ac[key] = [mappedValue]; } return ac; }, initialValue); }; /** * Correlates the elements of two sequences based on equality of keys and groups the results. * The default equality comparer is used to compare keys. */ List.prototype.GroupJoin = function (list, key1, key2, result) { return this.Select(function (x) { return result(x, list.Where(function (z) { return key1(x) === key2(z); })); }); }; /** * Returns the index of the first occurence of an element in the List. */ List.prototype.IndexOf = function (element) { return this._elements.indexOf(element); }; /** * Inserts an element into the List<T> at the specified index. */ List.prototype.Insert = function (index, element) { if (index < 0 || index > this._elements.length) { throw new Error('Index is out of range.'); } this._elements.splice(index, 0, element); }; /** * Produces the set intersection of two sequences by using the default equality comparer to compare values. */ List.prototype.Intersect = function (source) { return this.Where(function (x) { return source.Contains(x); }); }; /** * Correlates the elements of two sequences based on matching keys. The default equality comparer is used to compare keys. */ List.prototype.Join = function (list, key1, key2, result) { return this.SelectMany(function (x) { return list.Where(function (y) { return key2(y) === key1(x); }).Select(function (z) { return result(x, z); }); }); }; /** * Returns the last element of a sequence. */ List.prototype.Last = function (predicate) { if (this.Count()) { return predicate ? this.Where(predicate).Last() : this._elements[this.Count() - 1]; } throw Error('InvalidOperationException: The source sequence is empty.'); }; /** * Returns the last element of a sequence, or a default value if the sequence contains no elements. */ List.prototype.LastOrDefault = function (defaultValue) { return this.Count() ? this.Last() : defaultValue; }; /** * Retrieves a default comparer function based on the type of the provided sample value. * Only supports primitive types: number, string, and boolean. * * @param sample - A sample value used to determine its type. * @returns A comparison function suitable for the type of the sample, or undefined if unsupported. */ List.getComparer = function (sample) { var type = typeof sample; return List.comparers.get(type); }; /** * Gets the maximum value in a generic sequence. * @returns The maximum value in the sequence, or undefined if the sequence is empty. * @param comparerOrSelector - An optional custom comparison function or a selector function to select a value from each element for comparison. */ List.prototype.Max = function (comparerOrSelector) { if (this._elements.length === 0) return undefined; if (!comparerOrSelector) { // Max(): T | undefined; return this.getMaxElement(this._elements); } var fn = comparerOrSelector; if (!fn || fn.length > 2 || fn.length === 0) { throw new Error('InvalidOperationException: Invalid comparer or selector function provided.'); } if (fn.length === 1) { // Max<R>(selector: (e: T) => R): R | undefined; return this.getMaxElement(this._elements.map(fn)); } //fn.length === 2 // Max(comparer: (a: T, b: T) => number): T | undefined; return this.getMaxElement(this._elements, fn); }; /** * Returns the maximum value in a generic sequence. * @param elements - The array of elements to find the maximum from. * @param customComparer - An optional custom comparison function. */ List.prototype.getMaxElement = function (elements, customComparer) { if (elements.length === 0) { throw new Error('InvalidOperationException: Sequence contains no elements.'); } var comparerToUse = customComparer !== null && customComparer !== void 0 ? customComparer : List.getComparer(elements[0]); if (!comparerToUse) { throw new Error('InvalidOperationException: No comparer available.'); } return elements.reduce(function (currentMax, elem) { return comparerToUse(elem, currentMax) > 0 ? elem : currentMax; }, elements[0]); }; /** * Gets the minimum value in a generic sequence. * @returns The minimum value in the sequence, or undefined if the sequence is empty. * @param comparerOrSelector - An optional custom comparison function or a selector function to select a value from each element for comparison. */ List.prototype.Min = function (comparerOrSelector) { if (this._elements.length === 0) return undefined; if (!comparerOrSelector) { // Min(): T | undefined; return this.getMinElement(this._elements); } var fn = comparerOrSelector; if (!fn || fn.length > 2 || fn.length === 0) { throw new Error('InvalidOperationException: Invalid comparer or selector function provided.'); } if (fn.length === 1) { // Min<R>(selector: (e: T) => R): R | undefined; return this.getMinElement(this._elements.map(fn)); } //fn.length === 2 // Min(comparer: (a: T, b: T) => number): T | undefined; return this.getMinElement(this._elements, fn); }; /** * Returns the minimum value in a generic sequence. * @param elements - The array of elements to find the minimum from. * @param customComparer - An optional custom comparison function. */ List.prototype.getMinElement = function (elements, customComparer) { if (elements.length === 0) { throw new Error('InvalidOperationException: Sequence contains no elements.'); } var comparerToUse = customComparer !== null && customComparer !== void 0 ? customComparer : List.getComparer(elements[0]); if (!comparerToUse) { throw new Error('InvalidOperationException: No comparer available.'); } return elements.reduce(function (currentMin, elem) { return comparerToUse(elem, currentMin) < 0 ? elem : currentMin; }, elements[0]); }; /** * Filters the elements of a sequence based on a specified type. */ List.prototype.OfType = function (type) { var typeName; switch (type) { case Number: typeName = typeof 0; break; case String: typeName = typeof ''; break; case Boolean: typeName = typeof true; break; case Function: typeName = typeof function () { }; // tslint:disable-line no-empty break; default: typeName = null; break; } return typeName === null ? this.Where(function (x) { return x instanceof type; }).Cast() : this.Where(function (x) { return typeof x === typeName; }).Cast(); }; /** * Sorts the elements of a sequence in ascending order according to a key. */ List.prototype.OrderBy = function (keySelector, comparer) { if (comparer === void 0) { comparer = keyComparer(keySelector, false); } // tslint:disable-next-line: no-use-before-declare return new OrderedList(this._elements, comparer); }; /** * Sorts the elements of a sequence in descending order according to a key. */ List.prototype.OrderByDescending = function (keySelector, comparer) { if (comparer === void 0) { comparer = keyComparer(keySelector, true); } // tslint:disable-next-line: no-use-before-declare return new OrderedList(this._elements, comparer); }; /** * Performs a subsequent ordering of the elements in a sequence in ascending order according to a key. */ List.prototype.ThenBy = function (keySelector) { return this.OrderBy(keySelector); }; /** * Performs a subsequent ordering of the elements in a sequence in descending order, according to a key. */ List.prototype.ThenByDescending = function (keySelector) { return this.OrderByDescending(keySelector); }; /** * Removes the first occurrence of a specific object from the List<T>. */ List.prototype.Remove = function (element) { return this.IndexOf(element) !== -1 ? (this.RemoveAt(this.IndexOf(element)), true) : false; }; /** * Removes all the elements that match the conditions defined by the specified predicate. */ List.prototype.RemoveAll = function (predicate) { return this.Where(function (value, index, list) { return !predicate(value, index, list); }); }; /** * Removes the element at the specified index of the List<T>. */ List.prototype.RemoveAt = function (index) { this._elements.splice(index, 1); }; /** * Reverses the order of the elements in the entire List<T>. */ List.prototype.Reverse = function () { return new List(this._elements.reverse()); }; /** * Projects each element of a sequence into a new form. */ List.prototype.Select = function (selector) { return new List(this._elements.map(selector)); }; /** * Projects each element of a sequence to a List<any> and flattens the resulting sequences into one sequence. */ List.prototype.SelectMany = function (selector) { var _this = this; return this.Aggregate(function (ac, _, i) { return (ac.AddRange(_this.Select(selector) .ElementAt(i) .ToArray()), ac); }, new List()); }; /** * Determines whether two sequences are equal by comparing the elements by using the default equality comparer for their type. */ List.prototype.SequenceEqual = function (list) { return this.All(function (e) { return list.Contains(e); }); }; /** * Returns the only element of a sequence, and throws an exception if there is not exactly one element in the sequence. */ List.prototype.Single = function (predicate) { if (this.Count(predicate) !== 1) { throw new Error('The collection does not contain exactly one element.'); } return this.First(predicate); }; /** * Returns the only element of a sequence, or a default value if the sequence is empty; * this method throws an exception if there is more than one element in the sequence. */ List.prototype.SingleOrDefault = function (defaultValue) { return this.Count() ? this.Single() : defaultValue; }; /** * Bypasses a specified number of elements in a sequence and then returns the remaining elements. */ List.prototype.Skip = function (amount) { return new List(this._elements.slice(Math.max(0, amount))); }; /** * Omit the last specified number of elements in a sequence and then returns the remaining elements. */ List.prototype.SkipLast = function (amount) { return new List(this._elements.slice(0, -Math.max(0, amount))); }; /** * Bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements. */ List.prototype.SkipWhile = function (predicate) { var _this = this; return this.Skip(this.Aggregate(function (ac) { return (predicate(_this.ElementAt(ac)) ? ++ac : ac); }, 0)); }; /** * Computes the sum of the sequence of number values that are obtained by invoking * a transform function on each element of the input sequence. */ List.prototype.Sum = function (transform) { return transform ? this.Select(transform).Sum() : this.Aggregate(function (ac, v) { return (ac += +v); }, 0); }; /** * Returns a specified number of contiguous elements from the start of a sequence. */ List.prototype.Take = function (amount) { return new List(this._elements.slice(0, Math.max(0, amount))); }; /** * Returns a specified number of contiguous elements from the end of a sequence. */ List.prototype.TakeLast = function (amount) { return new List(this._elements.slice(-Math.max(0, amount))); }; /** * Returns elements from a sequence as long as a specified condition is true. */ List.prototype.TakeWhile = function (predicate) { var _this = this; return this.Take(this.Aggregate(function (ac) { return (predicate(_this.ElementAt(ac)) ? ++ac : ac); }, 0)); }; /** * Copies the elements of the List<T> to a new array. */ List.prototype.ToArray = function () { return this._elements; }; /** * Creates a Dictionary<TKey, TValue> from a List<T> according to a specified key selector function. */ List.prototype.ToDictionary = function (key, value) { var _this = this; return this.Aggregate(function (dicc, v, i) { // const dictionaryKey = String(this.Select(key).ElementAt(i)) // ;((dicc as unknown) as Record<string, T | TValue>)[dictionaryKey] = value // ? this.Select(value).ElementAt(i) // : v dicc.Add({ Key: _this.Select(key).ElementAt(i), Value: !!value ? _this.Select(value).ElementAt(i) : v }); return dicc; }, new List()); }; /** * Creates a List<T> from an Enumerable.List<T>. */ List.prototype.ToList = function () { return this; }; /** * Creates a Lookup<TKey, TElement> from an IEnumerable<T> according to specified key selector and element selector functions. */ List.prototype.ToLookup = function (keySelector, elementSelector) { return this.GroupBy(keySelector, elementSelector); }; /** * Produces the set union of two sequences by using the default equality comparer. */ List.prototype.Union = function (list) { return this.Concat(list).Distinct(); }; /** * Filters a sequence of values based on a predicate. */ List.prototype.Where = function (predicate) { return new List(this._elements.filter(predicate)); }; /** * Applies a specified function to the corresponding elements of two sequences, producing a sequence of the results. */ List.prototype.Zip = function (list, result) { var _this = this; return list.Count() < this.Count() ? list.Select(function (x, y) { return result(_this.ElementAt(y), x); }) : this.Select(function (x, y) { return result(x, list.ElementAt(y)); }); }; // A map of built-in primitive type names to their default comparison functions. // This supports number, string, and boolean only List.comparers = new Map([ ['number', function (a, b) { return a - b; }], ['string', function (a, b) { return a.localeCompare(b); }], ['boolean', function (a, b) { return Number(a) - Number(b); }] ]); return List; }()); /** * Represents a sorted sequence. The methods of this class are implemented by using deferred execution. * The immediate return value is an object that stores all the information that is required to perform the action. * The query represented by this method is not executed until the object is enumerated either by * calling its ToDictionary, ToLookup, ToList or ToArray methods */ var OrderedList = /** @class */ (function (_super) { __extends(OrderedList, _super); function OrderedList(elements, _comparer) { var _this = _super.call(this, elements) || this; _this._comparer = _comparer; _this._elements.sort(_this._comparer); return _this; } /** * Allows you to get the parent List out of the OrderedList * @override * @returns and ordered list turned into a regular List<T> */ OrderedList.prototype.ToList = function () { return new List(this._elements); }; /** * Performs a subsequent ordering of the elements in a sequence in ascending order according to a key. * @override */ OrderedList.prototype.ThenBy = function (keySelector) { return new OrderedList(this._elements, composeComparers(this._comparer, keyComparer(keySelector, false))); }; /** * Performs a subsequent ordering of the elements in a sequence in descending order, according to a key. * @override */ OrderedList.prototype.ThenByDescending = function (keySelector) { return new OrderedList(this._elements, composeComparers(this._comparer, keyComparer(keySelector, true))); }; return OrderedList; }(List)); export default List; //# sourceMappingURL=list.js.map