optimize appending multiple entries to ArrayState

This commit is contained in:
Niels Lyngsø
2023-01-25 10:41:34 +01:00
parent 3dc9446351
commit dea113ec8b
2 changed files with 49 additions and 20 deletions

View File

@@ -1,5 +1,5 @@
import { DeepState } from "./deep-state";
import { appendToFrozenArray } from "./append-to-frozen-array.method";
import { pushToUniqueArray } from "./push-to-unique-array.method";
/**
* @export
@@ -28,8 +28,8 @@ export class ArrayState<T> extends DeepState<T[]> {
* { key: 1, value: 'foo'},
* { key: 2, value: 'bar'}
* ];
* const mySubject = new ArrayState(data, (x) => x.key);
* mySubject.remove([1]);
* const myState = new ArrayState(data, (x) => x.key);
* myState.remove([1]);
*/
remove(uniques: unknown[]) {
let next = this.getValue();
@@ -59,8 +59,8 @@ export class ArrayState<T> extends DeepState<T[]> {
* { key: 2, value: 'bar'},
* { key: 3, value: 'poo'}
* ];
* const mySubject = new ArrayState(data, (x) => x.key);
* mySubject.filter((entry) => entry.key !== 1);
* const myState = new ArrayState(data, (x) => x.key);
* myState.filter((entry) => entry.key !== 1);
*
* Result:
* [
@@ -75,8 +75,8 @@ export class ArrayState<T> extends DeepState<T[]> {
}
/**
* @method append
* @param {Partial<T>} partialData - A object containing some of the data for this Subject.
* @method appendOne
* @param {T} entry - new data to be added in this Subject.
* @returns ArrayState<T>
* @description - Append some new data to this Subject.
* @example <caption>Example append some data.</caption>
@@ -84,11 +84,17 @@ export class ArrayState<T> extends DeepState<T[]> {
* { key: 1, value: 'foo'},
* { key: 2, value: 'bar'}
* ];
* const mySubject = new ArrayState(data);
* mySubject.append({ key: 1, value: 'replaced-foo'});
* const myState = new ArrayState(data);
* myState.append({ key: 1, value: 'replaced-foo'});
*/
appendOne(entry: T) {
this.next(appendToFrozenArray(this.getValue(), entry, this._getUnique))
const next = [...this.getValue()];
if(this._getUnique) {
pushToUniqueArray(next, entry, this._getUnique);
} else {
next.push(entry);
}
this.next(next);
return this;
}
@@ -102,21 +108,22 @@ export class ArrayState<T> extends DeepState<T[]> {
* { key: 1, value: 'foo'},
* { key: 2, value: 'bar'}
* ];
* const mySubject = new ArrayState(data);
* mySubject.append([
* const myState = new ArrayState(data);
* myState.append([
* { key: 1, value: 'replaced-foo'},
* { key: 3, value: 'another-bla'}
* ]);
*/
append(entries: T[]) {
// TODO: stop calling appendOne for each but make sure to handle this in one.
entries.forEach(x => this.appendOne(x))
/*
const unFrozenDataSet = [...this.getValue()];
this.next(unFrozenDataSet);
*/
if(this._getUnique) {
const next = [...this.getValue()];
entries.forEach(entry => {
pushToUniqueArray(next, entry, this._getUnique!);
});
this.next(next);
} else {
this.next([...this.getValue(), ...entries]);
}
return this;
}
}

View File

@@ -0,0 +1,22 @@
/**
* @export
* @method pushToUniqueArray
* @param {T[]} data - An array of objects.
* @param {T} entry - The object to insert or replace with.
* @param {getUniqueMethod: (entry: T) => unknown} [getUniqueMethod] - Method to get the unique value of an entry.
* @description - Append or replaces an item of an Array.
* @example <caption>Example append new entry for a Array. Where the key is unique and the item will be updated if matched with existing.</caption>
* const entry = {key: 'myKey', value: 'myValue'};
* const newDataSet = pushToUniqueArray([], entry, x => x.key === key);
* mySubject.next(newDataSet);
*/
export function pushToUniqueArray<T>(data: T[], entry: T, getUniqueMethod: (entry: T) => unknown): T[] {
const unique = getUniqueMethod(entry);
const indexToReplace = data.findIndex((x) => getUniqueMethod(x) === unique);
if (indexToReplace !== -1) {
data[indexToReplace] = entry;
} else {
data.push(entry);
}
return data;
}