@apicart/js-utils
Version:
A small set of useful utilities for easier development
147 lines (112 loc) • 3.11 kB
text/typescript
import { Loops } from '.';
class Objects {
public assign(object: Record<string, any>, keyPath: string|string[], value: any): void
{
if (typeof keyPath === 'string') {
keyPath = keyPath.split('.');
}
let key: string | number;
const lastKeyIndex = keyPath.length - 1;
for (let i = 0; i < lastKeyIndex; ++i) {
key = keyPath[i];
if (!(key in object)) {
object[key] = {};
}
object = object[key];
}
object[keyPath[lastKeyIndex]] = value;
}
public copy(object: Record<string, any>): Record<string, any>
{
const newObject = {};
Loops.forEach(object, (value: any, key: string | number): void => {
newObject[key] = this.isObject(value) ? this.copy(value) : value;
});
return newObject;
}
public delete(object: Record<string, any>, keyPath: string|string[]): void
{
if (typeof keyPath === 'string') {
keyPath = keyPath.split('.');
}
if (keyPath.length) {
Loops.forEach(keyPath, function (key: string | number): void | boolean {
if (this.isLast() || typeof object[key] !== 'object') {
return false;
}
object = object[key];
});
}
delete object[keyPath.pop()];
}
public find(object: Record<string, any>, keyPath: string|string[]): any | null
{
if (!keyPath || !object || typeof object !== 'object') {
return null;
}
if (typeof keyPath === 'string') {
keyPath = keyPath.split('.');
}
let wrongKeyPath = false;
if (keyPath.length) {
Loops.forEach(keyPath, (keyPathPart: string): void | boolean => {
if (object === null || typeof object !== 'object' || !(keyPathPart in object)) {
wrongKeyPath = true;
return false;
}
object = object[keyPathPart];
});
}
return wrongKeyPath ? null : object;
}
public keyExists(object: Record<string, any>, keyPath: string|string[]): boolean
{
if (!keyPath || !object || typeof object !== 'object') {
return false;
}
if (typeof keyPath === 'string') {
keyPath = keyPath.split('.');
}
let keyExists = true;
if (keyPath.length) {
Loops.forEach(keyPath, (keyPathPart: string): void | boolean => {
if (object === null || typeof object !== 'object' || !(keyPathPart in object)) {
keyExists = false;
return false;
}
object = object[keyPathPart];
});
} else {
keyExists = false;
}
return keyExists;
}
public isObject(data: any): boolean
{
if (typeof data === 'undefined' || data === null || Array.isArray(data)) {
return false;
}
return typeof data === 'object';
}
public merge(...objects: Record<string, any>[]): Record<string, any>
{
const newObject = {};
Loops.forEach(objects, (object: Record<string, any>): void => {
Loops.forEach(object, (value: any, key: string | number): void => {
newObject[key] = !(key in newObject) || !this.isObject(value)
? value
: this.merge(newObject[key], value);
});
});
return newObject;
}
public values(object: Record<string, any>): any[]
{
const values = [];
Loops.forEach(object, (value: any): void => {
values.push(value);
});
return values;
}
}
export default new Objects();