UNPKG

nhb-toolbox

Version:

A versatile collection of smart, efficient, and reusable utility functions and classes for everyday development needs.

162 lines (161 loc) 6.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createOptionsArray = createOptionsArray; exports.removeDuplicatesFromArray = removeDuplicatesFromArray; exports.getDuplicates = getDuplicates; exports.findMissingElements = findMissingElements; exports.splitArray = splitArray; exports.splitArrayByProperty = splitArrayByProperty; exports.rotateArray = rotateArray; exports.moveArrayElement = moveArrayElement; const non_primitives_1 = require("../guards/non-primitives"); const primitives_1 = require("../guards/primitives"); const index_1 = require("../utils/index"); const helpers_1 = require("./helpers"); /** * * Converts an array of objects into a formatted array of options. * * @param data - An array of objects to convert into options. * @param config - The configuration object to specify the keys for the `value` (firstFieldName) and `label` (secondFieldName) fields and rename as needed. * @returns An array of options, where each option has `value` and `label` fields as default or as specified by user in the config options. */ function createOptionsArray(data, config) { const { firstFieldKey, secondFieldKey, firstFieldName = 'value', secondFieldName = 'label', retainNumberValue = false, } = config || {}; if (data && data?.length) { return data?.map((datum) => { const firstValue = retainNumberValue && (0, primitives_1.isNumber)(datum[firstFieldKey]) ? datum[firstFieldKey] : String(datum[firstFieldKey] ?? ''); return { [firstFieldName]: firstValue, [secondFieldName]: String(datum[secondFieldKey] ?? ''), }; }); } else { return []; } } /** * * Removes duplicate values from an array, supporting deep comparison for objects and arrays. * * @param array - The array from which duplicates need to be removed. * @returns A new array with duplicates removed. */ function removeDuplicatesFromArray(array) { return array?.filter((item, index, self) => index === self?.findIndex((el) => (0, index_1.isDeepEqual)(el, item))); } /** * * Finds duplicate values in an array, runs deep comparison for objects and arrays. * * @param array - The array in which to find duplicates. * @returns An array containing all duplicate entries (each one only once). */ function getDuplicates(array) { const seen = []; const duplicates = []; for (const item of array) { const hasSeen = seen?.find((el) => (0, index_1.isDeepEqual)(el, item)); const hasDuplicate = duplicates?.find((el) => (0, index_1.isDeepEqual)(el, item)); if (hasSeen && !hasDuplicate) { duplicates?.push(item); } else if (!hasSeen) { seen?.push(item); } } return duplicates; } /** * * Finds elements missing from one array compared to another using deep comparison. * * @param options - Configuration to specify which array to compare and direction of check. * @returns An array of missing elements based on the comparison direction. */ /** * * Finds elements missing from one array compared to another using deep comparison. * * @param array1 The first array to compare. * @param array2 The second array to compare. * @param missingFrom Which direction to compare for missing values:. * - `'from-first'` → values in `array1` missing in `array2`. * - `'from-second'` → values in `array2` missing in `array1`. * @returns An array of missing elements based on the comparison direction. */ function findMissingElements(array1, array2, missingFrom) { const source = (missingFrom === 'from-first' ? array1 : array2) ?? []; const target = (missingFrom === 'from-first' ? array2 : array1) ?? []; return source.filter((s) => !target?.some((t) => (0, index_1.isDeepEqual)(t, s))); } /** * * Splits an array into chunks of a given size. * * @param arr The array to split. * @param chunkSize The size of each chunk. * @returns An array of chunked arrays. */ function splitArray(arr, chunkSize) { const result = []; for (let i = 0; i < arr?.length; i += chunkSize) { result.push(arr.slice(i, i + chunkSize)); } return result; } /** * * Group an array of objects by a specified key, returning only arrays of grouped objects. * * @param source - The source array of objects to group. * @param property - The property to group the array by. Property can be a string, number, boolean, undefined or null. Supports nested dot notation. * * @returns An array of grouped arrays. Each sub-array contains objects that share the same value for the specified property. * * @example * splitArrayByProperty([{ type: 'a' }, { type: 'b' }, { type: 'a' }, { type: undefined }], 'type') * // => [ [{ type: 'a' }, { type: 'a' }], [{ type: 'b' }], [{ type: undefined }] ] * * @notes * - Returns an empty array if the input is invalid or empty. * - Groups objects even when the group key is `undefined` or `null` (object with `null` & `undefined` property-values are grouped together). */ function splitArrayByProperty(source, property) { if (!(0, non_primitives_1.isValidArray)(source)) return []; const grouped = {}; source.forEach((item) => { const rawKey = (0, helpers_1._resolveNestedKey)(item, property); const key = rawKey != null ? String(rawKey) : '__undefined__'; if (!grouped[key]) { grouped[key] = []; } grouped[key].push(item); }); return Object.values(grouped); } /** * * Rotates an array left or right by a given number of steps. * * @param arr The array to rotate. * @param steps The number of positions to rotate (positive: right, negative: left). * @returns The rotated array. */ function rotateArray(arr, steps) { const length = arr?.length; if (length === 0) return arr; const offset = ((steps % length) + length) % length; return arr.slice(-offset).concat(arr.slice(0, -offset)); } /** * * Moves an element within an array from one index to another. * * @param arr The array to modify. * @param fromIndex The index of the element to move. * @param toIndex The new index for the element. * @returns A new array with the element moved. */ function moveArrayElement(arr, fromIndex, toIndex) { const newArr = [...arr]; const [item] = newArr.splice(fromIndex, 1); newArr.splice(toIndex, 0, item); return newArr; }