curray
Version:
Curray is an extension library for the native JavaScript Array object.
433 lines (422 loc) • 16.6 kB
JavaScript
/*!
* curray v1.0.12
* (c) Roger Far
* Released under the MIT License.
*/
(function (factory) {
typeof define === 'function' && define.amd ? define(factory) :
factory();
})((function () { 'use strict';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol */
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);
};
function __extends(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 __());
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
/**
* Creates a function that negates the result of the predicate
*/
var negate = function (predicate) {
return function (value, index, list) {
return !predicate(value, index, list);
};
};
var composeComparers = function (previousComparer, currentComparer) {
return function (a, b) {
return previousComparer(a, b) || currentComparer(a, b);
};
};
var keyComparer = function (keySelector, descending) {
if (descending === void 0) { descending = false; }
return function (a, b) {
var sortKeyA = keySelector(a);
var sortKeyB = keySelector(b);
if (sortKeyA > sortKeyB) {
return !descending ? 1 : -1;
}
else if (sortKeyA < sortKeyB) {
return !descending ? -1 : 1;
}
else {
return 0;
}
};
};
/**
* 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 OrderedArray = /** @class */ (function (_super) {
__extends(OrderedArray, _super);
/* istanbul ignore next */
function OrderedArray(elements, _comparer) {
var _this = _super.apply(this, elements) || this;
_this._comparer = _comparer;
Object.setPrototypeOf(_this, OrderedArray.prototype);
_this.sort(_this._comparer);
return _this;
}
Object.defineProperty(OrderedArray, Symbol.species, {
get: function () {
return Array;
},
enumerable: false,
configurable: true
});
/**
* Performs a subsequent ordering of the elements in a sequence in ascending order according to a key.
* @override
*/
OrderedArray.prototype.thenBy = function (keySelector) {
return new OrderedArray(this, composeComparers(this._comparer, keyComparer(keySelector, false)));
};
/**
* Performs a subsequent ordering of the elements in a sequence in descending order, according to a key.
* @override
*/
OrderedArray.prototype.thenByDescending = function (keySelector) {
return new OrderedArray(this, composeComparers(this._comparer, keyComparer(keySelector, true)));
};
return OrderedArray;
}(Array));
/**
* Adds the elements of the specified collection to the end of the List<T>.
*/
Array.prototype.addRange = function (elements) {
this.push.apply(this, elements);
};
/**
* Applies an accumulator function over a sequence.
*/
Array.prototype.aggregate = function (accumulator, initialValue) {
return this.reduce(accumulator, initialValue);
};
/**
* Determines whether all elements of a sequence satisfy a condition.
*/
Array.prototype.all = function (predicate) {
return this.every(predicate);
};
/**
* Determines whether a sequence contains any elements.
*/
Array.prototype.any = function (predicate) {
return predicate ? this.some(predicate) : this.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.
*/
Array.prototype.average = function (transform) {
return this.sum(transform) / this.length;
};
/**
* Casts the elements of a sequence to the specified type.
*/
Array.prototype.cast = function () {
return this;
};
/**
* Determines whether an element is in the Array<T>.
*/
Array.prototype.contains = function (element) {
return this.some(function (x) { return x === element; });
};
/**
* Returns the number of elements in a sequence.
*/
Array.prototype.count = function (predicate) {
return predicate ? this.where(predicate).count() : this.length;
};
/**
* Returns the elements of the specified sequence or the type parameter's default value
* in a singleton collection if the sequence is empty.
*/
Array.prototype.defaultIfEmpty = function (defaultValue) {
return this.count() ? this : [defaultValue];
};
/**
* Returns distinct elements from a sequence according to specified key selector.
*/
Array.prototype.distinctBy = function (keySelector) {
var groups = this.groupBy(keySelector);
return Object.keys(groups).reduce(function (res, key) {
var group = groups[key];
if (group != null && group.length > 0) {
res.push(group[0]);
}
return res;
}, new Array());
};
/**
* Returns the element at a specified index in a sequence.
*/
Array.prototype.elementAt = function (index) {
if (index < this.count() && index >= 0) {
return this[index];
}
else {
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.
*/
Array.prototype.elementAtOrDefault = function (index) {
return this.elementAt(index) !== undefined && this.elementAt(index);
};
/**
* Produces the set difference of two sequences by using the default equality comparer to compare values.
*/
Array.prototype.except = function (source) {
return this.where(function (x) { return !source.contains(x); });
};
/**
* Returns the first element of a sequence.
*/
Array.prototype.first = function (predicate) {
if (this.count()) {
return predicate ? this.where(predicate).first() : this[0];
}
else {
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.
*/
Array.prototype.firstOrDefault = function (predicate) {
return this.count(predicate) ? this.first(predicate) : null;
};
/**
* Groups the elements of a sequence according to a specified key selector function.
*/
Array.prototype.groupBy = function (grouper, mapper) {
var initialValue = {};
var thisMapper = mapper !== null && mapper !== void 0 ? mapper : (function (val) { return val; });
return this.aggregate(function (ac, v) {
var key = grouper(v);
var existingGroup = ac[key];
var mappedValue = thisMapper(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.
*/
Array.prototype.groupJoin = function (list, key1, key2, result) {
return this.select(function (x) {
return result(x, list.where(function (z) { return key1(x) === key2(z); }));
});
};
/**
* Produces the set intersection of two sequences by using the default equality comparer to compare values.
*/
Array.prototype.intersect = function (source) {
return this.where(function (x) { return source.contains(x); });
};
/**
* Returns the last element of a sequence.
*/
Array.prototype.last = function (predicate) {
if (this.count()) {
return predicate ? this.where(predicate).last() : this[this.count() - 1];
}
else {
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.
*/
Array.prototype.lastOrDefault = function (predicate) {
return this.count(predicate) ? this.last(predicate) : null;
};
/**
* Returns the maximum value in a generic sequence.
*/
Array.prototype.max = function (selector) {
var id = function (x) { return x; };
return Math.max.apply(Math, this.map(selector || id));
};
/**
* Returns the minimum value in a generic sequence.
*/
Array.prototype.min = function (selector) {
var id = function (x) { return x; };
return Math.min.apply(Math, this.map(selector || id));
};
/**
* Filters the elements of a sequence based on a specified type.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Array.prototype.ofType = function (type) {
var typeName;
switch (type) {
case Number:
typeName = 'number';
break;
case String:
typeName = 'string';
break;
case Boolean:
typeName = 'boolean';
break;
case Function:
typeName = 'function';
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.
*/
Array.prototype.orderBy = function (keySelector) {
return new OrderedArray(this, keyComparer(keySelector, false));
};
/**
* Sorts the elements of a sequence in descending order according to a key.
*/
Array.prototype.orderByDescending = function (keySelector) {
return new OrderedArray(this, keyComparer(keySelector, true));
};
/**
* Removes all the elements that match the conditions defined by the specified predicate.
*/
Array.prototype.removeAll = function (predicate) {
return this.where(negate(predicate));
};
/**
* Projects each element of a sequence into a new form.
*/
Array.prototype.select = function (selector) {
return this.map(selector);
};
/**
* Projects each element of a sequence to a Array<any> and flattens the resulting sequences into one sequence.
*/
Array.prototype.selectMany = function (selector) {
return this.reduce(function (acc, element, index) { return acc.concat(selector(element, index)); }, []);
};
/**
* Determines whether two sequences are equal by comparing the elements by using the default equality comparer for their type.
*/
Array.prototype.sequenceEqual = function (list) {
return !!this.reduce(function (x, y, z) {
return list[z] === y ? x : undefined;
});
};
/**
* Returns the only element of a sequence, and throws an exception if there is not exactly one element in the sequence.
*/
Array.prototype.single = function (predicate) {
if (this.count(predicate) !== 1) {
throw new Error('InvalidOperationException: The collection does not contain exactly one element.');
}
else {
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.
*/
Array.prototype.singleOrDefault = function (predicate) {
return this.count(predicate) ? this.single(predicate) : null;
};
/**
* Bypasses a specified number of elements in a sequence and then returns the remaining elements.
*/
Array.prototype.skip = function (amount) {
return this.slice(Math.max(0, amount));
};
/**
* Bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements.
*/
Array.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.
*/
Array.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.
*/
Array.prototype.take = function (amount) {
return this.slice(0, Math.max(0, amount));
};
/**
* Returns elements from a sequence as long as a specified condition is true.
*/
Array.prototype.takeWhile = function (predicate) {
var _this = this;
return this.take(this.aggregate(function (ac) { return (predicate(_this.elementAt(ac)) ? ++ac : ac); }, 0));
};
/**
* Produces the set union of two sequences by using the default equality comparer.
*/
Array.prototype.union = function (list) {
return this.concat(list).distinctBy(function (m) { return m; });
};
/**
* Filters a sequence of values based on a predicate.
*/
Array.prototype.where = function (predicate) {
return this.filter(predicate);
};
/**
* Applies a specified function to the corresponding elements of two sequences, producing a sequence of the results.
*/
Array.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)); });
};
}));
//# sourceMappingURL=index.umd.js.map