mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-03 23:55:04 +08:00
119 lines
3.3 KiB
JavaScript
Executable File
119 lines
3.3 KiB
JavaScript
Executable File
export default class OrderedIndexArray {
|
|
|
|
/**
|
|
* @param {(arrayElement: number) => number} comparisonValueSupplier
|
|
* @param {number} value
|
|
*/
|
|
constructor(comparisonValueSupplier = v => v, value = null) {
|
|
this.array = new Uint32Array(value)
|
|
this.comparisonValueSupplier = comparisonValueSupplier
|
|
this.length = 0
|
|
this.currentPosition = 0
|
|
}
|
|
|
|
/** @param {number} index */
|
|
get(index) {
|
|
if (index >= 0 && index < this.length) {
|
|
return this.array[index]
|
|
}
|
|
return null
|
|
}
|
|
|
|
getArray() {
|
|
return this.array
|
|
}
|
|
|
|
/** @param {number} value */
|
|
getPosition(value) {
|
|
let l = 0
|
|
let r = this.length
|
|
while (l < r) {
|
|
let m = Math.floor((l + r) / 2)
|
|
if (this.comparisonValueSupplier(this.array[m]) < value) {
|
|
l = m + 1
|
|
} else {
|
|
r = m
|
|
}
|
|
}
|
|
return l
|
|
}
|
|
|
|
reserve(length) {
|
|
if (this.array.length < length) {
|
|
let newArray = new Uint32Array(length)
|
|
newArray.set(this.array)
|
|
this.array = newArray
|
|
}
|
|
}
|
|
|
|
/** @param {number} element */
|
|
insert(element, comparisonValue = null) {
|
|
let position = this.getPosition(this.comparisonValueSupplier(element))
|
|
if (
|
|
position < this.currentPosition
|
|
|| comparisonValue != null && position == this.currentPosition && this.comparisonValueSupplier(element) < comparisonValue) {
|
|
++this.currentPosition
|
|
}
|
|
this.shiftRight(position)
|
|
this.array[position] = element
|
|
++this.length
|
|
return position
|
|
}
|
|
|
|
/** @param {number} element */
|
|
remove(element) {
|
|
let position = this.getPosition(this.comparisonValueSupplier(element))
|
|
if (this.array[position] == element) {
|
|
this.removeAt(position)
|
|
}
|
|
}
|
|
|
|
/** @param {number} position */
|
|
removeAt(position) {
|
|
if (position < this.currentPosition) {
|
|
--this.currentPosition
|
|
}
|
|
this.shiftLeft(position)
|
|
--this.length
|
|
return position
|
|
}
|
|
|
|
getNext() {
|
|
if (this.currentPosition >= 0 && this.currentPosition < this.length) {
|
|
return this.get(this.currentPosition)
|
|
}
|
|
return null
|
|
}
|
|
|
|
getNextValue() {
|
|
if (this.currentPosition >= 0 && this.currentPosition < this.length) {
|
|
return this.comparisonValueSupplier(this.get(this.currentPosition))
|
|
} else {
|
|
return Number.MAX_SAFE_INTEGER
|
|
}
|
|
}
|
|
|
|
getPrev() {
|
|
if (this.currentPosition > 0) {
|
|
return this.get(this.currentPosition - 1)
|
|
}
|
|
return null
|
|
}
|
|
|
|
getPrevValue() {
|
|
if (this.currentPosition > 0) {
|
|
return this.comparisonValueSupplier(this.get(this.currentPosition - 1))
|
|
} else {
|
|
return Number.MIN_SAFE_INTEGER
|
|
}
|
|
}
|
|
|
|
shiftLeft(leftLimit, steps = 1) {
|
|
this.array.set(this.array.subarray(leftLimit + steps), leftLimit)
|
|
}
|
|
|
|
shiftRight(leftLimit, steps = 1) {
|
|
this.array.set(this.array.subarray(leftLimit, -steps), leftLimit + steps)
|
|
}
|
|
}
|