Skip to content

Commit 98544a4

Browse files
committed
[array] add bubblesortItem
1 parent 2572461 commit 98544a4

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

array.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,39 @@ export const map = (arr, mapper) => {
182182
}
183183
return /** @type {any} */ (res)
184184
}
185+
186+
/**
187+
* This function bubble-sorts a single item to the correct position. The sort happens in-place and
188+
* might be useful to ensure that a single item is at the correct position in an otherwise sorted
189+
* array.
190+
*
191+
* @example
192+
* const arr = [3, 2, 5]
193+
* arr.sort((a, b) => a - b)
194+
* arr // => [2, 3, 5]
195+
* arr.splice(1, 0, 7)
196+
* array.bubbleSortItem(arr, 1, (a, b) => a - b)
197+
* arr // => [2, 3, 5, 7]
198+
*
199+
* @template T
200+
* @param {Array<T>} arr
201+
* @param {number} i
202+
* @param {(a:T,b:T) => number} compareFn
203+
*/
204+
export const bubblesortItem = (arr, i, compareFn) => {
205+
const n = arr[i]
206+
let j = i
207+
// try to sort to the right
208+
while (compareFn(n, arr[j + 1]) > 0) {
209+
arr[j] = arr[j + 1]
210+
arr[++j] = n
211+
}
212+
if (i === j && j > 0) { // no change yet
213+
// sort to the left
214+
while (compareFn(arr[j - 1], n) > 0) {
215+
arr[j] = arr[j - 1]
216+
arr[--j] = n
217+
}
218+
}
219+
return j
220+
}

array.test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as array from './array.js'
22
import * as t from './testing.js'
3+
import * as prng from './prng.js'
34

45
/**
56
* @param {t.TestCase} _tc
@@ -117,3 +118,29 @@ export const testUnique = _tc => {
117118
t.compare([{ el: 1 }], array.uniqueBy([{ el: 1 }, { el: 1 }], o => o.el))
118119
t.compare([], array.uniqueBy([], o => o))
119120
}
121+
122+
/**
123+
* @param {t.TestCase} tc
124+
*/
125+
export const testRepeatBubblesortItem = tc => {
126+
const arr = Array.from(prng.uint8Array(tc.prng, 10))
127+
arr.sort((a, b) => a - b)
128+
const newItem = prng.uint32(tc.prng, 0, 256)
129+
const pos = prng.uint32(tc.prng, 0, arr.length)
130+
arr.splice(pos, newItem)
131+
const arrCopySorted = arr.slice().sort((a, b) => a - b)
132+
array.bubblesortItem(arr, pos, (a, b) => a - b)
133+
t.compare(arr, arrCopySorted)
134+
}
135+
136+
/**
137+
* @param {t.TestCase} tc
138+
*/
139+
export const testRepeatBubblesort = tc => {
140+
const arr = Array.from(prng.uint8Array(tc.prng, 10))
141+
const arrCopySorted = arr.slice().sort((a, b) => a - b)
142+
for (let i = arr.length - 1; i >= 0; i--) {
143+
while (array.bubblesortItem(arr, i, (a, b) => a - b) !== i) { /* nop */ }
144+
}
145+
t.compare(arr, arrCopySorted)
146+
}

test.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"lib0/component": "./component.js",
2929
"lib0/conditions.js": "./conditions.js",
3030
"lib0/dist/conditions.cjs": "./dist/conditions.cjs",
31-
"lib0/conditions": "./condititons.js",
31+
"lib0/conditions": "./conditions.js",
3232
"lib0/crypto/jwt": "./crypto/jwt.js",
3333
"lib0/crypto/aes-gcm": "./crypto/aes-gcm.js",
3434
"lib0/crypto/ecdsa": "./crypto/ecdsa.js",

0 commit comments

Comments
 (0)