sussy-util
Version:
Util package made by me
356 lines (355 loc) • 12.7 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Functions_1 = require("../Functions");
const Optional_1 = __importDefault(require("./Optional"));
const Random_1 = __importDefault(require("./Random"));
class ArrayUtils {
constructor() { }
/**
* If the item is an array, then push the flattened array into the result array, otherwise push the
* item into the result array.
*
* @template T - The type of the elements in the array.
* @param {any[]} arr - any[] - The array to flatten.
*/
flat(arr) {
if (!Array.isArray(arr))
return [];
const result = [];
for (const item of arr) {
if (Array.isArray(item)) {
result.push(...this.flat(item));
}
else {
result.push(item);
}
}
return result;
}
/**
* It takes two arrays of the same type and returns an array of that type containing the elements
* that are common to both arrays
*
* @template T - The type of the elements in the array.
* @param {T[]} a - T[] - The first array to compare
* @param {T[]} b - T[]
* @returns An array of the elements that are in both a and b.
*/
intersection(a, b) {
if (!Array.isArray(a) || !Array.isArray(b))
return [];
return a.filter((x) => b.includes(x));
}
/**
* It takes two arrays, concatenates them, removes duplicates, and returns the result
*
* @template T - The type of the elements in the array.
* @param {T[]} a - T[] - The first array to union
* @param {T[]} b - T[]
* @returns An array of unique values from both arrays.
*/
union(a, b) {
if (!Array.isArray(a) || !Array.isArray(b))
return [];
return [...new Set([...a, ...b])];
}
/**
* It takes two arrays, and returns an array of all the elements in the first array that are not in
* the second array
*
* @template T - The type of the elements in the array.
* @param {T[]} a - T[] - The first array
* @param {T[]} b - T[] - The array to compare against
* @returns The difference between two arrays.
*/
difference(a, b) {
if (!Array.isArray(a) || !Array.isArray(b))
return [];
return a.filter((x) => !b.includes(x));
}
/**
* This function takes an array of any type and shuffles it in place.
*
* @template T - The type of array to shuffle
* @template X - The type of the elements in the array.
* @param {T | X[]} array - T | X[]
*/
shuffle(array) {
if (!Array.isArray(array))
return;
for (let i = array.length - 1; i > 0; i--) {
const j = Random_1.default.randomInt(0, i + 1);
[array[i], array[j]] = [array[j], array[i]];
}
}
/**
* It takes an array and a value, and returns the number of times the value occurs in the array.
*
* @template T - The type of the elements in the array.
* @param {T[]} array - T[] - The array to search in
* @param {T} value - T - The value to count occurrences of.
* @returns The number of occurrences of the value in the array.
*/
countOccurrences(array, value) {
if (!Array.isArray(array))
return 0;
return array.reduce((a, v) => (v === value ? a + 1 : a), 0);
}
/**
* It clears an array by setting its length to zero
*
* @template T - The type of the elements in the array.
* @param {any[]} array - any[]
*/
clear(array) {
if (!Array.isArray(array))
return;
array.length = 0;
}
/**
* It takes an array of any type, and returns a new array of the same type
*
* @template T - The type of the elements in the array.
* @param {T[]} array - T[] - The array to clone.
* @returns A new array with the same elements as the original array.
*/
clone(array) {
if (!Array.isArray(array))
return [];
return [...array];
}
/**
* It takes an array of any type, and returns a new array of the same type
*
* @template T - The type of the elements in the array.
* @param {T[]} array - T[] - The array to clone.
* @returns A new array with the same elements as the original array.
*/
deepClone(array) {
if (!Array.isArray(array))
return [];
return array.map(Functions_1.deepClone);
}
/**
* It takes an array of any type, and returns an array of the same type, with all duplicates
* removed
*
* @template T - The type of the elements in the array.
* @param {T[]} arr - T[] - The array to remove duplicates from.
* @returns A new array with the duplicates removed.
*/
removeDuplicates(arr) {
if (!Array.isArray(arr))
return [];
return [...new Set(arr)];
}
/**
* Sort an array of objects by a key of your choice.
*
* @template T - The type of the elements in the array.
* @param {T[]} arr - T[] - The array to sort
* @param key - keyof T
* @returns An array of objects.
*/
sortByKey(arr, key) {
if (!Array.isArray(arr) || !key)
return [];
return arr.sort((a, b) => {
if (a[key] > b[key])
return 1;
if (a[key] < b[key])
return -1;
return 0;
});
}
/**
* It takes an array and an item, and returns a new array with the item removed
*
* @template T - The type of the elements in the array.
* @param {T[]} arr - T[] - The array to remove the item from
* @param {T} item - The item to remove from the array.
* @returns A new array with all the items that are not equal to the item passed in.
*/
remove(arr, item) {
if (!Array.isArray(arr))
return [];
return arr.filter((val) => val !== item);
}
/**
* It takes two arrays of different types and returns an array of tuples
*
* @template T - The type of the elements in the first array.
* @template U - The type of the elements in the second array.
* @param {T[]} arr1 - T[]
* @param {U[]} arr2 - U[]
* @returns An array of tuples.
*/
zip(arr1, arr2) {
if (!Array.isArray(arr1) || !Array.isArray(arr2))
return [];
return arr1.map((val, i) => [val, arr2[i]]);
}
/**
* It takes an array, an index, and any number of items, and returns a new array with the items
* inserted at the index.
*
* @template T - The type of the elements in the array.
* @param {T[]} arr - T[] - The array to insert into
* @param {number} index - The index where you want to insert the items.
* @param {T[]} items - T[] - The items to insert into the array.
* @returns a new array with the items inserted at the specified index.
*/
insert(arr, index, ...items) {
if (!Array.isArray(arr))
return [];
if (index < 0)
index = 0;
if (index > arr.length)
index = arr.length;
return [...arr.slice(0, index), ...items, ...arr.slice(index)];
}
/**
* It takes an array and returns a new array with all the unique sub-arrays.
* @param {any[][]} arr - any[][] - The array to get the unique sub-arrays from.
* @returns A new array with all the unique sub-arrays.
*/
uniqueSubArrays(arr) {
if (!Array.isArray(arr))
return [];
const map = new Map(arr.map((v) => [JSON.stringify(v), v]));
return [...map.values()];
}
/**
* Finds the k-th smallest element in an array using the QuickSelect algorithm.
*
* @param {number[]} arr - The input array.
* @param {number} k - The index of the desired smallest element (1-based).
* @returns {number} The k-th smallest element in the array.
*/
quickSelect(arr, k) {
if (!Array.isArray(arr) || arr.length === 0) {
throw new Error('Array must be non-empty.');
}
if (k < 1 || k > arr.length) {
throw new Error('k must be between 1 and the length of the array.');
}
if (arr.length === 1)
return arr[0];
const pivotIndex = Random_1.default.randomInt(0, arr.length - 1);
const pivot = arr[pivotIndex];
const lows = arr.filter((x) => x < pivot);
const highs = arr.filter((x) => x > pivot);
const pivots = arr.filter((x) => x === pivot);
if (k <= lows.length) {
return this.quickSelect(lows, k);
}
if (k <= lows.length + pivots.length) {
return pivot;
}
return this.quickSelect(highs, k - lows.length - pivots.length);
}
/**
* Sorts an array in ascending order using the Quick Sort algorithm.
*
* @template T - The type of the elements in the array.
* @param {T[]} arr - The input array to be sorted.
* @param {Function} compareFn - A function to compare two elements.
* @returns {T[]} The sorted array.
*/
quickSort(arr, compareFn) {
if (!Array.isArray(arr))
return [];
if (arr.length <= 1 || typeof compareFn !== 'function')
return arr;
const pivot = arr[arr.length - 1];
const smaller = [];
const greater = [];
const equal = [];
for (let i = 0; i < arr.length; i++) {
const compareResult = compareFn(arr[i], pivot);
if (compareResult < 0) {
smaller.push(arr[i]);
}
else if (compareResult > 0) {
greater.push(arr[i]);
}
else {
equal.push(arr[i]);
}
}
const sortedSmaller = this.quickSort(smaller, compareFn);
const sortedGreater = this.quickSort(greater, compareFn);
return sortedSmaller.concat(equal, sortedGreater);
}
/**
* Splits an array into smaller arrays of a specified size.
*
* @template T - The type of the elements in the array.
* @param {T[]} array - The array to be chunked.
* @param {number} chunkSize - The size of each chunk.
* @returns {T[][]} - An array of smaller arrays (chunks).
*/
chunks(array, chunkSize) {
if (!Array.isArray(array) || chunkSize <= 0)
return [];
const chunkedArray = [];
for (let i = 0; i < array.length; i += chunkSize) {
const chunk = array.slice(i, i + chunkSize);
chunkedArray.push(chunk);
}
return chunkedArray;
}
/**
* Returns the found element or undefined in an Optional
*
* @template T - The type of the elements in the array.
* @param array the array to be searched
* @param property the property to be searched in
* @param value the value to be searched for
* @returns Optional object of the value
*/
findByPropertyValue(array, property, value) {
if (!Array.isArray(array))
return Optional_1.default.empty();
return Optional_1.default.ofNullable(array.find((x) => x[property] === value));
}
/**
* Returns the index of the first occurrence of a given value in an array.
*
* @template T - The type of the elements in the array.
* @param array the array to search in
* @param property the property to search on
* @param value the value to search for
* @returns the index of the value in the array, or -1 if not found
*/
findIndexByPropertyValue(array, property, value) {
if (!Array.isArray(array))
return -1;
return array.findIndex((x) => x[property] === value);
}
/**
* @template T - The type of the elements in the array.
* @param array the array to search
* @param condition the condition to search for
* @returns the indicies found in the array
*/
findAllIndices(array, condition) {
if (!Array.isArray(array))
return [];
const indices = [];
for (let i = 0; i < array.length; i++) {
if (condition(array[i])) {
indices.push(i);
}
}
return indices;
}
static getInstance() {
return this.instance;
}
}
ArrayUtils.instance = new ArrayUtils();
exports.default = ArrayUtils.getInstance();