[web] Make GroupByList class more maintainable

This commit is contained in:
Alain Nussbaumer 2023-12-12 21:20:41 +01:00
parent 7c9df8cc79
commit 5e04a9d22a
1 changed files with 20 additions and 87 deletions

View File

@ -120,10 +120,6 @@ export class GroupByList {
this.group(noop()) this.group(noop())
} }
get() {
return this.itemsByGroup
}
isEmpty() { isEmpty() {
return !this.items || this.items.length <= 0 return !this.items || this.items.length <= 0
} }
@ -143,98 +139,35 @@ export class GroupByList {
this.indexList = [...new Set(itemsSorted.map(options.groupKeyFn))] this.indexList = [...new Set(itemsSorted.map(options.groupKeyFn))]
// Group item list // Group item list
this.itemsByGroup = itemsSorted.reduce((r, item) => { this.itemsGrouped = itemsSorted.reduce((r, item) => {
const groupKey = options.groupKeyFn(item) const groupKey = options.groupKeyFn(item)
r[groupKey] = [...(r[groupKey] || []), item] r[groupKey] = [...(r[groupKey] || []), item]
return r return r
}, {}) }, {})
} }
[Symbol.iterator]() { *generate() {
/* for (const key in this.itemsGrouped) {
* Use a new index for each iterator. This makes multiple if (key !== GROUP_KEY_NONE) {
* iterations over the iterable safe for non-trivial cases, yield {
* such as use of break or nested looping over the same iterable. groupKey: key,
*/ itemId: key,
let groupIndex = -1 isItem: false,
let itemIndex = -1 item: {}
return {
next: () => {
if (this.isEmpty()) {
return { done: true }
} else if (groupIndex >= this.indexList.length) {
/*
* End of all groups and items reached
* This should never happen, as the we already
* return "done" after we reached the last item
* of the last group
*/
return { done: true }
} else if (groupIndex < 0) {
/*
* Start iterating
* Return the first group title as the next item
*/
++groupIndex
itemIndex = 0
if (this.indexList[groupIndex] !== GROUP_KEY_NONE) {
// Only return the group, if it is not the "noop" default group
return {
value: {
groupKey: this.indexList[groupIndex],
itemId: this.indexList[groupIndex],
isItem: false,
item: {}
},
done: false
}
}
} }
}
let currentGroupKey = this.indexList[groupIndex] for (const item of this.itemsGrouped[key]) {
let currentGroupItems = this.itemsByGroup[currentGroupKey] yield {
groupKey: key,
if (itemIndex < currentGroupItems.length) { itemId: item.id,
/* isItem: true,
* Within a group with remaining items item: item
* Return the current item and increment the item index
*/
const currentItem = this.itemsByGroup[currentGroupKey][itemIndex++]
return {
value: {
groupKey: currentGroupKey,
itemId: currentItem.id,
isItem: true,
item: currentItem
},
done: false
}
} }
/*
* End of the current groups item list reached
* Move to the next group and return the group key/title
* as the next item
*/
++groupIndex
itemIndex = 0
if (groupIndex < this.indexList.length) {
currentGroupKey = this.indexList[groupIndex]
return {
value: {
groupKey: currentGroupKey,
itemId: currentGroupKey,
isItem: false,
item: {}
},
done: false
}
}
// No group left, we are done iterating
return { done: true }
} }
} }
} }
[Symbol.iterator]() {
return this.generate()
}
} }