terriajs
Version:
Geospatial data visualization platform.
97 lines (94 loc) • 2.83 kB
text/typescript
import ModelTraits from "./ModelTraits";
import TraitsConstructor from "./TraitsConstructor";
import StratumFromTraits from "../Models/Definition/StratumFromTraits";
import createStratumInstance from "../Models/Definition/createStratumInstance";
/**
* A strata map where the strata are obtained from a sub-property of another
* parent strata map.
*/
export default class NestedStrataMap<T extends ModelTraits> implements Map<
string,
T
> {
constructor(
readonly parentTraitsClass: TraitsConstructor<ModelTraits>,
readonly parent: Map<string, StratumFromTraits<ModelTraits>>,
readonly parentProperty: string
) {}
clear(): void {
this.parent.forEach((value: any) => {
value[this.parentProperty] = undefined;
});
}
delete(key: string): boolean {
const parentValue: any = this.parent.get(key);
if (parentValue === undefined) {
return false;
}
const hasValue = parentValue[this.parentProperty] !== undefined;
parentValue[this.parentProperty] = undefined;
return hasValue;
}
forEach(
callbackfn: (value: T, key: string, map: Map<string, T>) => void,
thisArg?: any
): void {
this.parent.forEach((parentValue: any, key: string) => {
const value = parentValue[this.parentProperty];
if (value !== undefined) {
callbackfn.call(thisArg, value, key, this);
}
});
}
get(key: string): T | undefined {
const parentValue: any = this.parent.get(key);
return parentValue && parentValue[this.parentProperty];
}
has(key: string): boolean {
return this.parent.has(key);
}
set(key: string, value: T): this {
let parentValue: any = this.parent.get(key);
if (parentValue === undefined) {
parentValue = createStratumInstance(this.parentTraitsClass);
this.parent.set(key, parentValue);
}
parentValue[this.parentProperty] = value;
return this;
}
get size(): number {
return this.parent.size;
}
[Symbol.iterator](): MapIterator<[string, T]> {
return this.entries();
}
*entries(): MapIterator<[string, T]> {
for (const entry of this.parent.entries()) {
const parentValue: any = entry[1];
const value = parentValue[this.parentProperty];
if (value === undefined) {
continue;
}
yield [entry[0], value];
}
}
*keys(): MapIterator<string> {
// Only return keys that have a value.
for (const entry of this.entries()) {
yield entry[0];
}
}
*values(): MapIterator<T> {
for (const entry of this.parent.entries()) {
const parentValue: any = entry[1];
const value = parentValue[this.parentProperty];
if (value === undefined) {
continue;
}
yield value;
}
}
get [Symbol.toStringTag](): string {
return new Map(this.entries()).toString();
}
}