dashersupply/src/types/deep-array.ts

76 lines
3.0 KiB
TypeScript

export class DeepArray<T> extends Array<T> {
public constructor(array: T[]|Array<T>|DeepArray<T>) {
// console.log("Constructing DeepArray<T> with array =", array);
super();
this.push(...array);
}
public mapRecursive<FromT, ToT>(this: FromT[], callbackfn: (value: FromT, index: number, array: DeepArray<FromT>) => ToT, childrenPropertyName: string): DeepArray<ToT> | undefined {
if(!childrenPropertyName){
throw "mapRecursive requires parameter `childrenPropertyName`";
}
const result: DeepArray<ToT> = new DeepArray([]);
this.forEach((element: any) => {
if (Array.isArray(element[childrenPropertyName])) {
result.push(...(new DeepArray<FromT>(element[childrenPropertyName])).mapRecursive<FromT,ToT>(callbackfn, childrenPropertyName) as ToT[]);
} else {
result.push(callbackfn(element, 0, new DeepArray<FromT>(this)));
}
});
return result;
}
public findRecursive<T>(this: DeepArray<T>, predicate: (value: T) => boolean, childrenPropertyName: string): T | undefined {
if(!childrenPropertyName){
throw "findRecursive requires parameter `childrenPropertyName`";
}
let initialFind = this.find(predicate);
if (initialFind) {
return initialFind;
}
let elementsWithChildren = this.asArray().filter((x: any, index: number, array: T[]) => { return x[childrenPropertyName] });
if (elementsWithChildren.length) {
let childElements: T[] = [];
elementsWithChildren.forEach((x: any) => {
if (x[childrenPropertyName])
childElements.push(...x[childrenPropertyName]);
});
return new DeepArray<T>(childElements).findRecursive(predicate, childrenPropertyName);
}
return undefined;
}
public asArray<T>(this: T[]): T[] {
let a: T[] = [];
a.push(...this);
return a;
}
}
/**
* @example
* // How to use this module:
* // Example usage:
* type Simple = string;
* interface Complex {
* interestingProperty: Simple;
* recursiveChildren?: Complex[];
* }
* let deepArray = new DeepArray<Complex>([ { interestingProperty: 'a', recursiveChildren: [ { interestingProperty: 'b' } ] }]);
* // Example 1: Map from Complex to Simple.
* deepArray.mapRecursive<Complex, Simple>((complex) => complex.interestingProperty, 'recursiveChildren');
* // Example 2: Find an element deeply in the tree.
* let result = deepArray.findRecursive<Complex>((complex) => complex.interestingProperty === 'b', 'recursiveChildren');
*/
// How to use this module:
// Example usage:
type Simple = string;
interface Complex {
interestingProperty: Simple;
recursiveChildren?: Complex[];
}
let deepArray = new DeepArray<Complex>([ { interestingProperty: 'a', recursiveChildren: [ { interestingProperty: 'b' } ] }]);
// Example 1: Map from Complex to Simple.
deepArray.mapRecursive<Complex, Simple>((complex) => complex.interestingProperty, 'recursiveChildren');
// Example 2: Find an element deeply in the tree.
console.log("Checkpoint 3");
let result = deepArray.findRecursive<Complex>((complex) => complex.interestingProperty === 'b', 'recursiveChildren');