Skip to content

Commit

Permalink
IncludeExcludeList model for managing and serializing favorites/exclu…
Browse files Browse the repository at this point in the history
…de items
  • Loading branch information
mitchcapper committed Aug 11, 2023
1 parent bd9d252 commit d164770
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions src/model/IncludeExcludeList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import * as _ from 'lodash';

export enum IEList { //these are flags so no direct equals, nothing requires them to be used as flags, but it would allow you to have an entry on both Include and Favorite at the same type
Invalid = 0,
Include = 1 << 1,
Exclude = 1 << 2,
Favorite = 1 << 3,
}

function* mapIterableImpl<T, U>(f: (val: T) => U, iterable: Iterable<T>): Iterable<U> {
for (const item of iterable) {
yield f(item);
}
}
const mapIterable = <T, U>(f: (val: T) => U) => (iterable: Iterable<T>) => mapIterableImpl(f, iterable);
function* filterIterableImpl<T>(f: (item: T) => boolean, iterable: Iterable<T>): Iterable<T> {
for (const item of iterable) {
if (f(item)) {
yield item;
}
}
}
const filterIterable = <T>(f: (val: T) => boolean) => (iterable: Iterable<T>) => filterIterableImpl(f, iterable);

interface SerializeData<ListKeyType>{
known : Map<ListKeyType, IEList>;
}

export class IncludeExcludeList<ListKeyType> {

protected known = new Map<ListKeyType, IEList>();

GetSaveDataObject() : Object {
return {known:new Map(this.known)} as SerializeData<ListKeyType>;
}
static LoadFromSaveDataObject<ListKeyType>(object : object) : IncludeExcludeList<ListKeyType> {
let ret = new IncludeExcludeList<ListKeyType>();
ret.known = new Map((object as SerializeData<ListKeyType>).known);
return ret;
}

AddOrUpdateToList = (key: ListKeyType, list: IEList) => this.known.set(key, list);
RemoveFromLists = (key: ListKeyType) => this.known.delete(key);
ClearList(list: IEList){
let keys = this.GetKeysOnList(list);
for (const key of keys)
this.RemoveFromList(key,list);
}
RemoveFromList(key: ListKeyType, list: IEList){
let current = this.GetKeyList(key);
if (current == undefined)
return;
current &= ~list;
if (current == IEList.Invalid)
this.known.delete(key);
else
this.AddOrUpdateToList(key, current);
}

GetKeyList = (key: ListKeyType) => this.known.get(key);
GetKeysOnList(list: IEList) : ListKeyType[] {
let filtered = filterIterable((kvp : [ListKeyType, IEList]) => (kvp[1] & list) != 0)(this.known.entries());
let mapped = mapIterable((kvp : [ListKeyType, IEList]) => kvp[0])(filtered);
return Array.from( mapped );
}
IsKeyOnList(key : ListKeyType, list: IEList, trueIfUnknown : boolean = false){
let val = this.GetKeyList(key);
if (val === undefined)
return trueIfUnknown;
return (val & list) != 0;
}
/// returnUnknown true if you want items not on any list, false if they should be excluded
FilterArrayAgainstList(arr: Iterable<ListKeyType>, list: IEList, returnUnknown : boolean = false) : Iterable<ListKeyType>{
return filterIterable( (key : ListKeyType) => this.IsKeyOnList(key,list,returnUnknown))(arr);
}
/// return the list in the same order passed in except all items that are on the specified list are returned first
* SortArrayAgainstList(arr: Iterable<ListKeyType>, list: IEList) : IterableIterator<ListKeyType> {
let after = new Array() as Array<ListKeyType>;
for (const item of arr) {
if (this.IsKeyOnList(item,list))
yield item;
else
after.push(item);
}
for (const itm of after)
yield itm;
}

}

0 comments on commit d164770

Please sign in to comment.