UNPKG

nhb-toolbox

Version:

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

145 lines (144 loc) 5.43 kB
/** * * Converts the values of specified keys in an object or array of objects to either string or number. * * Supports nested objects using dot-notation keys. * * @param data The object or array of objects to convert. * @param options Options object specifying the conversion mapping. * - `keys`: The keys in the object to be converted (dot-notation supported). * - `convertTo`: The target type, either "string" or "number". * @returns The modified object or array of objects with the converted values, with updated types. */ export function convertObjectValues(data, options) { const { keys, convertTo } = options; /** * Helper function to determine if value should be preserved. */ const _shouldPreserveValue = (value) => convertTo === 'number' && (typeof value !== 'string' || isNaN(Number(value))); /** * Helper function to resolve a dot-notation key path and modify the corresponding value in the object. */ const _setValueAtPath = (obj, path, convertTo) => { const segments = path.split('.'); let current = obj; segments?.forEach((key, index) => { if (index === segments?.length - 1) { const value = current?.[key]; if (_shouldPreserveValue(value)) { return; } if (convertTo === 'string' && typeof value !== 'string') { current[key] = String(value); } else if (convertTo === 'number' && typeof value !== 'number' && !isNaN(Number(value))) { current[key] = Number(value); } } else { if (typeof current?.[key] === 'object' && current?.[key] !== null) { current = current?.[key]; } else { current[key] = {}; current = current?.[key]; } } }); return obj; }; /** * Recursively process a single object. */ const _convertValue = (obj) => { let newObj = structuredClone(obj); keys?.forEach((key) => { newObj = _setValueAtPath(newObj, key, convertTo); }); return newObj; }; if (Array.isArray(data)) { return data?.map((d) => _convertValue(d)); } return _convertValue(data); } /** * * Pick specific fields from an object and create a new object with specified fields. * * @description This function creates a new object containing only the specified fields from the source object. * It is useful for creating a new object with a subset of properties from an existing object. * * @param T The type of the source object. * @param U The type of the keys to pick from the source object. * * @param source The source object from which to pick fields. * @param keys The keys of the fields to pick from the source object. * * @returns An object containing only the picked fields. */ export function pickFields(source, keys) { const result = {}; keys?.forEach((key) => { result[key] = source?.[key]; }); return result; } /** * * Create a new object by removing specific keys from the source object. * * @param source - The original (source) object from which to delete fields. * @param keys - An array of keys (fields) to remove from the object. * * @returns A new object without the specified keys. * * @example * deleteFields({ a: 1, b: 2, c: 3 }, ['b']) * // => { a: 1, c: 3 } * * @notes * - Does not mutate the original object. * - Useful for excluding sensitive or unwanted fields. */ export function deleteFields(source, keys) { const result = {}; for (const key in source) { if (!keys.includes(key)) { result[key] = source?.[key]; } } return result; } /** * * Pick specific fields from an object based on a given condition. * * @description This function creates a new object containing only the fields that satisfy the given condition. * The condition can be based on the field's value or type, depending on the implementation. * * @param T The type of the source object. * * @param source The source object from which to pick fields. * @param condition A function that takes the key and value of a property and returns a boolean indicating whether the property should be picked. * * @returns An object containing only the fields that satisfy the condition. */ export function pickObjectFieldsByCondition(source, condition) { const result = {}; Object.entries(source)?.forEach(([key, value]) => { if (condition(key, value)) { result[key] = value; } }); return result; } /** * * Remap fields from one object to another. * @description This function creates a new object with fields remapped from the source object to the target object based on the provided field map. * * @param source The source object from which to remap fields. * @param fieldMap An object that maps target keys to source keys. * @returns An object with fields remapped according to the field map. */ export function remapFields(source, fieldMap) { const result = {}; for (const targetKey in fieldMap) { const sourceKey = fieldMap?.[targetKey]; result[targetKey] = source?.[sourceKey]; } return result; }