You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 regels
1.5 KiB

  1. export class MRU<T> {
  2. private stack: T[] = [];
  3. constructor(public readonly maxSize: number = 10, private readonly comparator?: (a: T, b: T) => boolean) {}
  4. get count(): number {
  5. return this.stack.length;
  6. }
  7. private _position: number = 0;
  8. get position(): number {
  9. return this._position;
  10. }
  11. add(item: T): void {
  12. if (this._position > 0) {
  13. this.stack.splice(0, this._position);
  14. this._position = 0;
  15. }
  16. const index =
  17. this.comparator != null ? this.stack.findIndex(i => this.comparator!(item, i)) : this.stack.indexOf(item);
  18. if (index !== -1) {
  19. this.stack.splice(index, 1);
  20. } else if (this.stack.length === this.maxSize) {
  21. this.stack.pop();
  22. }
  23. this.stack.unshift(item);
  24. this._position = 0;
  25. }
  26. get(position?: number): T | undefined {
  27. if (position != null) {
  28. if (position < 0 || position >= this.stack.length) return undefined;
  29. return this.stack[position];
  30. }
  31. return this.stack.length > 0 ? this.stack[0] : undefined;
  32. }
  33. insert(item: T): void {
  34. if (this._position > 0) {
  35. this.stack.splice(0, this._position);
  36. this._position = 0;
  37. }
  38. this.stack.unshift(item);
  39. this._position++;
  40. }
  41. navigate(direction: 'back' | 'forward'): T | undefined {
  42. if (this.stack.length <= 1) return undefined;
  43. if (direction === 'back') {
  44. if (this._position >= this.stack.length - 1) return undefined;
  45. this._position += 1;
  46. } else {
  47. if (this._position <= 0) return undefined;
  48. this._position -= 1;
  49. }
  50. return this.stack[this._position];
  51. }
  52. }