data-structures-and-algorithms/heapq Home Manual Reference Source

src/nsmallest.js

  1. import {min} from '@iterable-iterator/reduce';
  2. import {sorted} from '@iterable-iterator/sorted';
  3. import {forwardRangeIterator} from '@iterable-iterator/range';
  4. import {iter} from '@iterable-iterator/iter';
  5. import {_zip2} from '@iterable-iterator/zip';
  6. import {reversed} from '@total-order/reversed';
  7.  
  8. import {keeporder} from './core/index.js';
  9.  
  10. import heapify from './heapify.js';
  11. import heapreplace from './heapreplace.js';
  12.  
  13. export default function nsmallest(compare, n, iterable) {
  14. if (n === 1) {
  15. const sentinel = {};
  16.  
  17. const result = min(compare, iterable, sentinel);
  18.  
  19. return result === sentinel ? [] : [result];
  20. }
  21.  
  22. if (iterable.length !== undefined && n >= iterable.length)
  23. return sorted(compare, iterable);
  24.  
  25. const it = iter(iterable);
  26.  
  27. const result = Array.from(
  28. _zip2(forwardRangeIterator(0, n, 1), it),
  29. ([i, elem]) => [elem, i],
  30. );
  31.  
  32. if (result.length === 0) return result;
  33.  
  34. const h = heapify(keeporder(reversed(compare)), result);
  35.  
  36. let top = result[0][0];
  37.  
  38. let order = n;
  39.  
  40. for (const elem of it) {
  41. if (compare(elem, top) < 0) {
  42. heapreplace(h, [elem, order]);
  43.  
  44. top = result[0][0];
  45.  
  46. ++order;
  47. }
  48. }
  49.  
  50. return sorted(
  51. compare,
  52. Array.from(result, (r) => r[0]),
  53. );
  54. }