PushQueue

推入队列,循环数组实现

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/432936/1161000/PushQueue.js

  1. /* exported PushQueue */
  2. /**
  3. * PushQueue
  4. *
  5. * 推入队列,循环数组实现。
  6. * @template T 数据类型
  7. * @version 1.1.2.20230313
  8. * @author Laster2800
  9. * @see {@link https://gitee.com/liangjiancang/userscript/tree/master/lib/PushQueue PushQueue}
  10. */
  11. class PushQueue {
  12. /** @type {number} 起始元素位置(指向起始元素后方) */
  13. index = 0
  14. /** @type {number} 队列长度 */
  15. size = 0
  16. /** @type {number} 最大长度 */
  17. maxSize = 0
  18. /** @type {T[]} 内部数据 */
  19. data = null
  20.  
  21. /**
  22. * @param {number} maxSize 队列的最大长度,达到此长度后继续推入数据,将舍弃队头处的数据
  23. */
  24. constructor(maxSize) {
  25. this.maxSize = maxSize
  26. this.data = new Array(maxSize)
  27. }
  28.  
  29. /**
  30. * 设置推入队列的最大长度
  31. * @param {number} maxSize 最大长度
  32. */
  33. setMaxSize(maxSize) {
  34. if (this.size > maxSize) {
  35. this.size = maxSize
  36. }
  37. const data = this.toArray().reverse()
  38. this.maxSize = maxSize
  39. this.index = data.length
  40. data.length = maxSize
  41. this.data = data
  42. }
  43.  
  44. /**
  45. * 向队尾推入数据,若队列已达到最大长度,则舍弃队头处数据
  46. * @param {T} value 推入队列的数据
  47. */
  48. enqueue(value) {
  49. this.data[this.index] = value
  50. this.index += 1
  51. if (this.index >= this.maxSize) {
  52. this.index = 0
  53. }
  54. if (this.size < this.maxSize) {
  55. this.size += 1
  56. }
  57. }
  58.  
  59. /**
  60. * 将队头处的数据弹出
  61. * @returns {T} 弹出的数据
  62. */
  63. dequeue() {
  64. if (this.size <= 0) return
  65. let index = this.index - this.size
  66. if (index < 0) {
  67. index += this.maxSize
  68. }
  69. this.size -= 1
  70. const result = this.data[index]
  71. delete this.data[index]
  72. return result
  73. }
  74.  
  75. /**
  76. * 获取第 `n` 个元素(范围 `[0, size - 1]`)
  77. * @param {number} n 元素位置
  78. * @returns {T} 第 `n` 个元素
  79. */
  80. get(n) {
  81. if (n < 0 || n >= this.size) return
  82. let index = this.index - n - 1
  83. if (index < 0) {
  84. index += this.maxSize
  85. }
  86. return this.data[index]
  87. }
  88.  
  89. /**
  90. * 设置第 `n` 个元素的值为 `value`(范围 `[0, size - 1]`,且第 `n` 个元素必须已存在)
  91. * @param {number} n 元素位置
  92. * @param {T} value 要设置的值
  93. * @returns {boolean} 是否设置成功
  94. */
  95. set(n, value) {
  96. if (n < 0 || n >= this.size) return false
  97. let index = this.index - n - 1
  98. if (index < 0) {
  99. index += this.maxSize
  100. }
  101. this.data[index] = value
  102. return true
  103. }
  104.  
  105. /**
  106. * 将推入队列以数组的形式返回
  107. * @param {number} [maxLength=size] 读取的最大长度
  108. * @param {number} [offset=0] 起始点
  109. * @returns {Array<T>} 队列数据的数组形式
  110. */
  111. toArray(maxLength = this.size, offset = 0) {
  112. if (offset < 0) {
  113. offset = 0
  114. }
  115. if (offset + maxLength > this.size) {
  116. maxLength = this.size - offset
  117. }
  118. const ar = []
  119. let start = this.index - offset
  120. if (start < 0) {
  121. start += this.maxSize
  122. }
  123. let end = start - maxLength
  124. for (let i = start - 1; i >= end && i >= 0; i--) {
  125. ar.push(this.data[i])
  126. }
  127. if (end < 0) {
  128. end += this.maxSize
  129. for (let i = this.maxSize - 1; i >= end; i--) {
  130. ar.push(this.data[i])
  131. }
  132. }
  133. return ar
  134. }
  135.  
  136. /**
  137. * 标准迭代器:`item`
  138. * @returns {IterableIterator<T>}
  139. */
  140. [Symbol.iterator]() {
  141. const iterator = this.entries()
  142. return {
  143. next: () => {
  144. const n = iterator.next()
  145. if (!n.done) {
  146. n.value = n.value[1]
  147. }
  148. return n
  149. },
  150. }
  151. }
  152.  
  153. /**
  154. * 迭代器:`[index, item]`
  155. * @returns {IterableIterator<[index: number, item: T]>}
  156. */
  157. entries() {
  158. let current = this.index - 1
  159. let end = this.index - this.size
  160. return {
  161. next: () => {
  162. if (current < 0 && end < 0) {
  163. current += this.maxSize
  164. end += this.maxSize
  165. }
  166. if (current < end || current < 0) return { done: true }
  167. const n = { value: [current, this.data[current]], done: false }
  168. current -= 1
  169. return n
  170. },
  171.  
  172. [Symbol.iterator]() { return this },
  173. }
  174. }
  175. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址