@tim-code/my-util 0.5.7 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tim-code/my-util",
3
- "version": "0.5.7",
3
+ "version": "0.5.8",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "author": "Tim Sprowl",
package/src/array.js CHANGED
@@ -221,18 +221,23 @@ function maxHeapify(heap, compare) {
221
221
  * Get the first N elements of the sorted array efficiently.
222
222
  * @template T
223
223
  * @param {Array<T>} array
224
- * @param {number} N
225
- * @param {Function} compare
224
+ * @param {Object} $1
225
+ * @param {number} $1.N Number of elements to return
226
+ * @param {Function=} $1.compare Sort function. Default is ascending sort.
227
+ * @param {boolean=} $1.unsorted If true, returns the final result in heap order, not sorted order, as an optimization.
228
+ * Default is false.
229
+ * @param {boolean=} $1.force If true, will force heap-based method for small N instead of more efficient "normal" way.
230
+ * Default is false.
226
231
  * @returns {Array<T>}
227
232
  */
228
- export function sortN(array, N, compare = ascending()) {
229
- if (N <= 0) {
233
+ export function sortN(array, { N, compare = ascending(), unsorted = false, force = false }) {
234
+ if (!(N > 0)) {
230
235
  return []
231
236
  }
232
237
  if (N >= array.length) {
233
238
  return [...array].sort(compare)
234
239
  }
235
- if (array.length <= 100 && N / array.length >= 0.1) {
240
+ if (!force && array.length <= 100 && N / array.length >= 0.1) {
236
241
  // seems to be faster to do it the "normal" way in this case
237
242
  return [...array].sort(compare).slice(0, N)
238
243
  }
@@ -245,5 +250,8 @@ export function sortN(array, N, compare = ascending()) {
245
250
  siftDown(heap, 0, compare)
246
251
  }
247
252
  }
253
+ if (unsorted) {
254
+ return heap
255
+ }
248
256
  return heap.sort(compare)
249
257
  }
package/src/array.test.js CHANGED
@@ -514,38 +514,42 @@ describe("multilevel", () => {
514
514
 
515
515
  describe("sortN", () => {
516
516
  it("returns empty array when N <= 0", () => {
517
- expect(sortN([1, 2, 3], 0)).toEqual([])
518
- expect(sortN([1, 2, 3], -5)).toEqual([])
517
+ expect(sortN([1, 2, 3], { N: 0, force: true })).toEqual([])
518
+ expect(sortN([1, 2, 3], { N: -5, force: true })).toEqual([])
519
519
  })
520
520
 
521
521
  it("returns the entire array sorted when N >= array.length and does not mutate original", () => {
522
522
  const arr = [3, 1, 2]
523
- const result = sortN(arr, 10)
523
+ const result = sortN(arr, { N: 10, force: true })
524
524
  expect(result).toEqual([1, 2, 3])
525
525
  expect(arr).toEqual([3, 1, 2])
526
526
  expect(result).not.toBe(arr)
527
527
  })
528
528
 
529
529
  it("returns the first N smallest elements (default ascending comparator)", () => {
530
- expect(sortN([5, 1, 3, 2, 4], 3)).toEqual([1, 2, 3])
531
- expect(sortN([3, 1, 3, 2, 2], 4)).toEqual([1, 2, 2, 3])
530
+ expect(sortN([5, 1, 3, 2, 4], { N: 3, force: true })).toEqual([1, 2, 3])
531
+ expect(sortN([3, 1, 3, 2, 2], { N: 4, force: true })).toEqual([1, 2, 2, 3])
532
532
  })
533
533
 
534
534
  it("respects a descending comparator (returns top N largest)", () => {
535
535
  const arr = [5, 1, 3, 2, 4]
536
- expect(sortN(arr, 2, descending())).toEqual([5, 4])
536
+ expect(sortN(arr, { N: 2, compare: descending(), force: true })).toEqual([5, 4])
537
537
  })
538
538
 
539
539
  it("works with key-based comparator and defers undefined/null values to the end", () => {
540
540
  const arr = [{ v: 3 }, {}, { v: 1 }, { v: null }, { v: 2 }, { v: undefined }]
541
- const out = sortN(arr, 3, ascending("v"))
541
+ const out = sortN(arr, { N: 3, compare: ascending("v"), force: true })
542
542
  expect(out.map((o) => o.v)).toEqual([1, 2, 3])
543
543
  })
544
544
 
545
545
  it("does not mutate the original array when N < array.length", () => {
546
546
  const arr = [5, 1, 3, 2, 4]
547
- const out = sortN(arr, 3)
547
+ const out = sortN(arr, { N: 3, force: true })
548
548
  expect(out).toEqual([1, 2, 3])
549
549
  expect(arr).toEqual([5, 1, 3, 2, 4])
550
550
  })
551
+
552
+ it("returns the first N smallest elements (default ascending comparator)", () => {
553
+ expect(sortN([10, 1, 7, 3, 5], { N: 3, force: true, unsorted: true })).toEqual([5, 1, 3])
554
+ })
551
555
  })