Skip to content

Commit d164770

Browse files
committed
IncludeExcludeList model for managing and serializing favorites/exclude items
1 parent bd9d252 commit d164770

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

src/model/IncludeExcludeList.ts

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import * as _ from 'lodash';
2+
3+
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
4+
Invalid = 0,
5+
Include = 1 << 1,
6+
Exclude = 1 << 2,
7+
Favorite = 1 << 3,
8+
}
9+
10+
function* mapIterableImpl<T, U>(f: (val: T) => U, iterable: Iterable<T>): Iterable<U> {
11+
for (const item of iterable) {
12+
yield f(item);
13+
}
14+
}
15+
const mapIterable = <T, U>(f: (val: T) => U) => (iterable: Iterable<T>) => mapIterableImpl(f, iterable);
16+
function* filterIterableImpl<T>(f: (item: T) => boolean, iterable: Iterable<T>): Iterable<T> {
17+
for (const item of iterable) {
18+
if (f(item)) {
19+
yield item;
20+
}
21+
}
22+
}
23+
const filterIterable = <T>(f: (val: T) => boolean) => (iterable: Iterable<T>) => filterIterableImpl(f, iterable);
24+
25+
interface SerializeData<ListKeyType>{
26+
known : Map<ListKeyType, IEList>;
27+
}
28+
29+
export class IncludeExcludeList<ListKeyType> {
30+
31+
protected known = new Map<ListKeyType, IEList>();
32+
33+
GetSaveDataObject() : Object {
34+
return {known:new Map(this.known)} as SerializeData<ListKeyType>;
35+
}
36+
static LoadFromSaveDataObject<ListKeyType>(object : object) : IncludeExcludeList<ListKeyType> {
37+
let ret = new IncludeExcludeList<ListKeyType>();
38+
ret.known = new Map((object as SerializeData<ListKeyType>).known);
39+
return ret;
40+
}
41+
42+
AddOrUpdateToList = (key: ListKeyType, list: IEList) => this.known.set(key, list);
43+
RemoveFromLists = (key: ListKeyType) => this.known.delete(key);
44+
ClearList(list: IEList){
45+
let keys = this.GetKeysOnList(list);
46+
for (const key of keys)
47+
this.RemoveFromList(key,list);
48+
}
49+
RemoveFromList(key: ListKeyType, list: IEList){
50+
let current = this.GetKeyList(key);
51+
if (current == undefined)
52+
return;
53+
current &= ~list;
54+
if (current == IEList.Invalid)
55+
this.known.delete(key);
56+
else
57+
this.AddOrUpdateToList(key, current);
58+
}
59+
60+
GetKeyList = (key: ListKeyType) => this.known.get(key);
61+
GetKeysOnList(list: IEList) : ListKeyType[] {
62+
let filtered = filterIterable((kvp : [ListKeyType, IEList]) => (kvp[1] & list) != 0)(this.known.entries());
63+
let mapped = mapIterable((kvp : [ListKeyType, IEList]) => kvp[0])(filtered);
64+
return Array.from( mapped );
65+
}
66+
IsKeyOnList(key : ListKeyType, list: IEList, trueIfUnknown : boolean = false){
67+
let val = this.GetKeyList(key);
68+
if (val === undefined)
69+
return trueIfUnknown;
70+
return (val & list) != 0;
71+
}
72+
/// returnUnknown true if you want items not on any list, false if they should be excluded
73+
FilterArrayAgainstList(arr: Iterable<ListKeyType>, list: IEList, returnUnknown : boolean = false) : Iterable<ListKeyType>{
74+
return filterIterable( (key : ListKeyType) => this.IsKeyOnList(key,list,returnUnknown))(arr);
75+
}
76+
/// return the list in the same order passed in except all items that are on the specified list are returned first
77+
* SortArrayAgainstList(arr: Iterable<ListKeyType>, list: IEList) : IterableIterator<ListKeyType> {
78+
let after = new Array() as Array<ListKeyType>;
79+
for (const item of arr) {
80+
if (this.IsKeyOnList(item,list))
81+
yield item;
82+
else
83+
after.push(item);
84+
}
85+
for (const itm of after)
86+
yield itm;
87+
}
88+
89+
}

0 commit comments

Comments
 (0)